All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Tan <pyokagan@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Schindelin <johannes.schindelin@gmx.de>,
	Stefan Beller <sbeller@google.com>, Paul Tan <pyokagan@gmail.com>
Subject: [PATCH v6 08/45] builtin-am: apply patch with git-apply
Date: Mon, 20 Jul 2015 00:10:00 +0800	[thread overview]
Message-ID: <1437322237-29863-9-git-send-email-pyokagan@gmail.com> (raw)
In-Reply-To: <1437322237-29863-1-git-send-email-pyokagan@gmail.com>

Implement applying the patch to the index using git-apply.

If a file is unchanged but stat-dirty, git-apply may erroneously fail to
apply patches, thinking that they conflict with a dirty working tree.

As such, since 2a6f08a (am: refresh the index at start and --resolved,
2011-08-15), git-am will refresh the index before applying patches.
Re-implement this behavior.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
---

Notes:
    v6
    
    * refresh_and_write_cache(): use a heap-allocated lock_file instead of a
      static-allocated one to allow the function to be reentrant.
    
    * refresh_and_write_cache(): remove the rollback_lock_file() -- since we
      ensure that the write_locked_index() succeeds there is no need to call
      it.

 builtin/am.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/builtin/am.c b/builtin/am.c
index 63f0fa4..1f198e4 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -10,6 +10,7 @@
 #include "dir.h"
 #include "run-command.h"
 #include "quote.h"
+#include "lockfile.h"
 
 /**
  * Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -42,6 +43,14 @@ static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp)
 	return 0;
 }
 
+/**
+ * Returns the length of the first line of msg.
+ */
+static int linelen(const char *msg)
+{
+	return strchrnul(msg, '\n') - msg;
+}
+
 enum patch_format {
 	PATCH_FORMAT_UNKNOWN = 0,
 	PATCH_FORMAT_MBOX
@@ -540,6 +549,19 @@ static const char *msgnum(const struct am_state *state)
 }
 
 /**
+ * Refresh and write index.
+ */
+static void refresh_and_write_cache(void)
+{
+	struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
+
+	hold_locked_index(lock_file, 1);
+	refresh_cache(REFRESH_QUIET);
+	if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
+		die(_("unable to write index file"));
+}
+
+/**
  * Parses `mail` using git-mailinfo, extracting its patch and authorship info.
  * state->msg will be set to the patch message. state->author_name,
  * state->author_email and state->author_date will be set to the patch author's
@@ -629,10 +651,35 @@ finish:
 }
 
 /**
+ * Applies current patch with git-apply. Returns 0 on success, -1 otherwise.
+ */
+static int run_apply(const struct am_state *state)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	cp.git_cmd = 1;
+
+	argv_array_push(&cp.args, "apply");
+	argv_array_push(&cp.args, "--index");
+	argv_array_push(&cp.args, am_path(state, "patch"));
+
+	if (run_command(&cp))
+		return -1;
+
+	/* Reload index as git-apply will have modified it. */
+	discard_cache();
+	read_cache();
+
+	return 0;
+}
+
+/**
  * Applies all queued mail.
  */
 static void am_run(struct am_state *state)
 {
+	refresh_and_write_cache();
+
 	while (state->cur <= state->last) {
 		const char *mail = am_path(state, msgnum(state));
 
@@ -645,7 +692,27 @@ static void am_run(struct am_state *state)
 		write_author_script(state);
 		write_commit_msg(state);
 
-		/* NEEDSWORK: Patch application not implemented yet */
+		printf_ln(_("Applying: %.*s"), linelen(state->msg), state->msg);
+
+		if (run_apply(state) < 0) {
+			int advice_amworkdir = 1;
+
+			printf_ln(_("Patch failed at %s %.*s"), msgnum(state),
+				linelen(state->msg), state->msg);
+
+			git_config_get_bool("advice.amworkdir", &advice_amworkdir);
+
+			if (advice_amworkdir)
+				printf_ln(_("The copy of the patch that failed is found in: %s"),
+						am_path(state, "patch"));
+
+			exit(128);
+		}
+
+		/*
+		 * NEEDSWORK: After the patch has been applied to the index
+		 * with git-apply, we need to make commit as well.
+		 */
 
 next:
 		am_next(state);
@@ -707,6 +774,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, prefix, options, usage, 0);
 
+	if (read_index_preload(&the_index, NULL) < 0)
+		die(_("failed to read the index"));
+
 	if (am_in_progress(&state))
 		am_load(&state);
 	else {
-- 
2.5.0.rc2.110.gb39b692

  parent reply	other threads:[~2015-07-19 16:11 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-19 16:09 [PATCH v6 00/45] Make git-am a builtin Paul Tan
2015-07-19 16:09 ` [PATCH v6 01/45] wrapper: implement xopen() Paul Tan
2015-07-19 16:09 ` [PATCH v6 02/45] wrapper: implement xfopen() Paul Tan
2015-07-19 16:09 ` [PATCH v6 03/45] builtin-am: implement skeletal builtin am Paul Tan
2015-07-19 16:09 ` [PATCH v6 04/45] builtin-am: implement patch queue mechanism Paul Tan
2015-07-19 16:09 ` [PATCH v6 05/45] builtin-am: split out mbox/maildir patches with git-mailsplit Paul Tan
2015-07-19 16:09 ` [PATCH v6 06/45] builtin-am: auto-detect mbox patches Paul Tan
2015-07-19 16:09 ` [PATCH v6 07/45] builtin-am: extract patch and commit info with git-mailinfo Paul Tan
2015-07-19 16:10 ` Paul Tan [this message]
2015-07-19 16:10 ` [PATCH v6 09/45] builtin-am: implement committing applied patch Paul Tan
2015-07-19 16:10 ` [PATCH v6 10/45] builtin-am: refuse to apply patches if index is dirty Paul Tan
2015-07-19 16:10 ` [PATCH v6 11/45] builtin-am: implement --resolved/--continue Paul Tan
2015-07-19 16:10 ` [PATCH v6 12/45] builtin-am: don't parse mail when resuming Paul Tan
2015-07-19 16:10 ` [PATCH v6 13/45] builtin-am: implement --skip Paul Tan
2015-07-19 16:10 ` [PATCH v6 14/45] builtin-am: implement --abort Paul Tan
2015-07-31 23:42   ` Stefan Beller
2015-07-19 16:10 ` [PATCH v6 15/45] builtin-am: reject patches when there's a session in progress Paul Tan
2015-07-19 16:10 ` [PATCH v6 16/45] builtin-am: implement -q/--quiet Paul Tan
2015-07-19 16:10 ` [PATCH v6 17/45] builtin-am: exit with user friendly message on failure Paul Tan
2015-07-19 16:10 ` [PATCH v6 18/45] builtin-am: implement -s/--signoff Paul Tan
2015-07-19 16:10 ` [PATCH v6 19/45] cache-tree: introduce write_index_as_tree() Paul Tan
2015-07-19 16:10 ` [PATCH v6 20/45] builtin-am: implement --3way, am.threeWay Paul Tan
2015-07-19 16:10 ` [PATCH v6 21/45] builtin-am: implement --rebasing mode Paul Tan
2015-07-19 16:10 ` [PATCH v6 22/45] builtin-am: bypass git-mailinfo when --rebasing Paul Tan
2015-07-19 16:10 ` [PATCH v6 23/45] builtin-am: handle stray state directory Paul Tan
2015-07-19 16:10 ` [PATCH v6 24/45] builtin-am: implement -u/--utf8 Paul Tan
2015-07-19 16:10 ` [PATCH v6 25/45] builtin-am: implement -k/--keep, --keep-non-patch Paul Tan
2015-07-19 16:10 ` [PATCH v6 26/45] builtin-am: implement --[no-]message-id, am.messageid Paul Tan
2015-07-19 16:10 ` [PATCH v6 27/45] builtin-am: support --keep-cr, am.keepcr Paul Tan
2015-07-19 16:10 ` [PATCH v6 28/45] builtin-am: implement --[no-]scissors Paul Tan
2015-07-19 16:10 ` [PATCH v6 29/45] builtin-am: pass git-apply's options to git-apply Paul Tan
2015-07-19 16:10 ` [PATCH v6 30/45] builtin-am: implement --ignore-date Paul Tan
2015-07-19 16:10 ` [PATCH v6 31/45] builtin-am: implement --committer-date-is-author-date Paul Tan
2015-07-19 16:10 ` [PATCH v6 32/45] builtin-am: implement -S/--gpg-sign, commit.gpgsign Paul Tan
2015-07-19 16:10 ` [PATCH v6 33/45] builtin-am: invoke post-rewrite hook Paul Tan
2015-07-19 16:10 ` [PATCH v6 34/45] builtin-am: support automatic notes copying Paul Tan
2015-07-19 16:10 ` [PATCH v6 35/45] builtin-am: invoke applypatch-msg hook Paul Tan
2015-07-19 16:10 ` [PATCH v6 36/45] builtin-am: invoke pre-applypatch hook Paul Tan
2015-07-19 16:10 ` [PATCH v6 37/45] builtin-am: invoke post-applypatch hook Paul Tan
2015-07-19 16:10 ` [PATCH v6 38/45] builtin-am: rerere support Paul Tan
2015-07-19 16:10 ` [PATCH v6 39/45] builtin-am: support and auto-detect StGit patches Paul Tan
2015-07-19 16:10 ` [PATCH v6 40/45] builtin-am: support and auto-detect StGit series files Paul Tan
2015-07-19 16:10 ` [PATCH v6 41/45] builtin-am: support and auto-detect mercurial patches Paul Tan
2015-07-19 16:10 ` [PATCH v6 42/45] builtin-am: implement -i/--interactive Paul Tan
2015-07-19 16:10 ` [PATCH v6 43/45] builtin-am: implement legacy -b/--binary option Paul Tan
2015-07-19 16:10 ` [PATCH v6 44/45] builtin-am: check for valid committer ident Paul Tan
2015-07-19 16:10 ` [PATCH v6 45/45] builtin-am: remove redirection to git-am.sh Paul Tan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1437322237-29863-9-git-send-email-pyokagan@gmail.com \
    --to=pyokagan@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=johannes.schindelin@gmx.de \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.