git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / 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/WIP v3 05/31] am: split out mbox/maildir patches with git-mailsplit
Date: Thu, 18 Jun 2015 19:25:17 +0800	[thread overview]
Message-ID: <1434626743-8552-6-git-send-email-pyokagan@gmail.com> (raw)
In-Reply-To: <1434626743-8552-1-git-send-email-pyokagan@gmail.com>

git-am.sh supports mbox, stgit and mercurial patches. Re-implement
support for splitting out mbox/maildirs using git-mailsplit, while also
implementing the framework required to support other patch formats in
the future.

Re-implement support for the --patch-format option (since a5a6755
(git-am foreign patch support: introduce patch_format, 2009-05-27)) to
allow the user to choose between the different patch formats.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
---

Notes:
    v3
    
    * Moved the TODO comment to the previous patch

 builtin/am.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 3 deletions(-)

diff --git a/builtin/am.c b/builtin/am.c
index af68c51..e9a3687 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -8,6 +8,12 @@
 #include "exec_cmd.h"
 #include "parse-options.h"
 #include "dir.h"
+#include "run-command.h"
+
+enum patch_format {
+	PATCH_FORMAT_UNKNOWN = 0,
+	PATCH_FORMAT_MBOX
+};
 
 struct am_state {
 	/* state directory path */
@@ -16,6 +22,9 @@ struct am_state {
 	/* current and last patch numbers, 1-indexed */
 	int cur;
 	int last;
+
+	/* number of digits in patch filename */
+	int prec;
 };
 
 /**
@@ -26,6 +35,8 @@ static void am_state_init(struct am_state *state)
 	memset(state, 0, sizeof(*state));
 
 	strbuf_init(&state->dir, 0);
+
+	state->prec = 4;
 }
 
 /**
@@ -111,13 +122,69 @@ static void am_destroy(const struct am_state *state)
 }
 
 /**
+ * Splits out individual patches from `paths`, where each path is either a mbox
+ * file or a Maildir. Return 0 on success, -1 on failure.
+ */
+static int split_patches_mbox(struct am_state *state, struct string_list *paths)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	struct string_list_item *item;
+	struct strbuf last = STRBUF_INIT;
+
+	cp.git_cmd = 1;
+	argv_array_push(&cp.args, "mailsplit");
+	argv_array_pushf(&cp.args, "-d%d", state->prec);
+	argv_array_pushf(&cp.args, "-o%s", state->dir.buf);
+	argv_array_push(&cp.args, "-b");
+	argv_array_push(&cp.args, "--");
+
+	for_each_string_list_item(item, paths)
+		argv_array_push(&cp.args, item->string);
+
+	if (capture_command(&cp, &last, 8))
+		return -1;
+
+	state->cur = 1;
+	state->last = strtol(last.buf, NULL, 10);
+
+	return 0;
+}
+
+/**
+ * Splits out individual patches, of patch_format, contained within paths.
+ * These patches will be stored in the state directory, with each patch's
+ * filename being its index, padded to state->prec digits. state->cur will be
+ * set to the index of the first patch, and state->last will be set to the
+ * index of the last patch.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int split_patches(struct am_state *state, enum patch_format patch_format,
+		struct string_list *paths)
+{
+	switch (patch_format) {
+	case PATCH_FORMAT_MBOX:
+		return split_patches_mbox(state, paths);
+	default:
+		die("BUG: invalid patch_format");
+	}
+	return -1;
+}
+
+/**
  * Setup a new am session for applying patches
  */
-static void am_setup(struct am_state *state)
+static void am_setup(struct am_state *state, enum patch_format patch_format,
+		struct string_list *paths)
 {
 	if (mkdir(state->dir.buf, 0777) < 0 && errno != EEXIST)
 		die_errno(_("failed to create directory '%s'"), state->dir.buf);
 
+	if (split_patches(state, patch_format, paths) < 0) {
+		am_destroy(state);
+		die(_("Failed to split patches."));
+	}
+
 	write_file(am_path(state, "next"), 1, "%d", state->cur);
 
 	write_file(am_path(state, "last"), 1, "%d", state->last);
@@ -148,7 +215,23 @@ static void am_run(struct am_state *state)
 	am_destroy(state);
 }
 
+/**
+ * parse_options() callback that validates and sets opt->value to the
+ * PATCH_FORMAT_* enum value corresponding to `arg`.
+ */
+static int parse_opt_patchformat(const struct option *opt, const char *arg, int unset)
+{
+	int *opt_value = opt->value;
+
+	if (!strcmp(arg, "mbox"))
+		*opt_value = PATCH_FORMAT_MBOX;
+	else
+		return -1;
+	return 0;
+}
+
 static struct am_state state;
+static int opt_patch_format;
 
 static const char * const am_usage[] = {
 	N_("git am [options] [(<mbox>|<Maildir>)...]"),
@@ -156,6 +239,8 @@ static const char * const am_usage[] = {
 };
 
 static struct option am_options[] = {
+	OPT_CALLBACK(0, "patch-format", &opt_patch_format, N_("format"),
+		N_("format the patch(es) are in"), parse_opt_patchformat),
 	OPT_END()
 };
 
@@ -185,8 +270,21 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 
 	if (am_in_progress(&state))
 		am_load(&state);
-	else
-		am_setup(&state);
+	else {
+		struct string_list paths = STRING_LIST_INIT_DUP;
+		int i;
+
+		for (i = 0; i < argc; i++) {
+			if (is_absolute_path(argv[i]) || !prefix)
+				string_list_append(&paths, argv[i]);
+			else
+				string_list_append(&paths, mkpath("%s/%s", prefix, argv[i]));
+		}
+
+		am_setup(&state, opt_patch_format, &paths);
+
+		string_list_clear(&paths, 0);
+	}
 
 	am_run(&state);
 
-- 
2.1.4

  parent reply	other threads:[~2015-06-18 11:26 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-18 11:25 [PATCH/WIP v3 00/31] Make git-am a builtin Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 01/31] wrapper: implement xopen() Paul Tan
2015-06-24 16:28   ` Johannes Schindelin
2015-06-24 16:59     ` Stefan Beller
2015-06-24 18:39       ` Johannes Schindelin
2015-07-01  9:41         ` Paul Tan
2015-07-01  9:53           ` Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 02/31] wrapper: implement xfopen() Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 03/31] am: implement skeletal builtin am Paul Tan
2015-06-18 20:26   ` Junio C Hamano
2015-06-19  9:56     ` Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 04/31] am: implement patch queue mechanism Paul Tan
2015-06-18 17:47   ` Stefan Beller
2015-06-18 20:43   ` Junio C Hamano
2015-06-19 12:49     ` Paul Tan
2015-06-24 14:59   ` Johannes Schindelin
2015-06-25 15:16     ` Paul Tan
2015-06-18 11:25 ` Paul Tan [this message]
2015-06-18 20:52   ` [PATCH/WIP v3 05/31] am: split out mbox/maildir patches with git-mailsplit Junio C Hamano
2015-06-18 11:25 ` [PATCH/WIP v3 06/31] am: detect mbox patches Paul Tan
2015-06-18 21:02   ` Junio C Hamano
2015-06-24  8:41     ` Paul Tan
2015-06-24 15:10   ` Johannes Schindelin
2015-06-25 13:40     ` Paul Tan
2015-06-26  7:42       ` Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 07/31] am: extract patch, message and authorship with git-mailinfo Paul Tan
2015-06-18 21:10   ` Junio C Hamano
2015-06-19  9:22     ` Paul Tan
2015-06-19 16:13       ` Junio C Hamano
2015-06-24  7:54         ` Paul Tan
2015-06-24 15:59           ` Junio C Hamano
2015-06-25 11:54             ` Paul Tan
     [not found]       ` <CAPc5daVbpB_T4cY1xvLrBKPUZw0JNMXqNAOsKE-R7NPO2nrnZA@mail.gmail.com>
2015-06-19 16:15         ` Paul Tan
2015-06-19 20:12           ` Johannes Schindelin
2015-06-24 16:36   ` Johannes Schindelin
2015-06-26  8:11     ` Paul Tan
2015-06-26 20:41       ` Junio C Hamano
2015-06-18 11:25 ` [PATCH/WIP v3 08/31] am: apply patch with git-apply Paul Tan
2015-06-18 21:23   ` Junio C Hamano
2015-06-18 11:25 ` [PATCH/WIP v3 09/31] am: commit applied patch Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 10/31] am: refresh the index at start Paul Tan
2015-06-18 21:28   ` Junio C Hamano
2015-06-19  8:07     ` Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 11/31] am: refuse to apply patches if index is dirty Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 12/31] am: implement --resolved/--continue Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 13/31] am: implement --skip Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 14/31] am: implement --abort Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 15/31] am: don't accept patches when there's a session in progress Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 16/31] am: implement quiet option Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 17/31] am: exit with user friendly message on patch failure Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 18/31] am: implement am --signoff Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 19/31] cache-tree: introduce write_index_as_tree() Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 20/31] am: implement 3-way merge Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 21/31] am: --rebasing Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 22/31] am: don't use git-mailinfo if --rebasing Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 23/31] am: handle stray state directory Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 24/31] am: implement -k/--keep, --keep-non-patch Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 25/31] am: implement --[no-]message-id, am.messageid Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 26/31] am: support --keep-cr, am.keepcr Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 27/31] am: implement --[no-]scissors Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 28/31] am: pass git-apply's options to git-apply Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 29/31] am: implement --ignore-date Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 30/31] am: implement --committer-date-is-author-date Paul Tan
2015-06-18 11:25 ` [PATCH/WIP v3 31/31] am: implement -S/--gpg-sign, commit.gpgsign 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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=1434626743-8552-6-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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).