git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.de>
To: git@vger.kernel.org
Subject: [RFC 2/3] am: semi working --cover-at-tip
Date: Mon, 13 Nov 2017 18:13:36 +0100	[thread overview]
Message-ID: <948b19c2-9f2d-de9d-1e0a-6681dc9317a9@suse.de> (raw)
In-Reply-To: <xmqqbmk68o9d.fsf@gitster.mtv.corp.google.com>

Issue with empty patch detection

Signed-off-by: Nicolas Morey-Chaisemartin <nicolas@morey-chaisemartin.com>
---
 builtin/am.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 126 insertions(+), 17 deletions(-)

diff --git a/builtin/am.c b/builtin/am.c
index 92c485350..702cbf8e0 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -111,6 +111,11 @@ struct am_state {
 	char *msg;
 	size_t msg_len;
 
+	/* Series metadata */
+	int series_id;
+	int series_len;
+	int cover_id;
+
 	/* when --rebasing, records the original commit the patch came from */
 	struct object_id orig_commit;
 
@@ -131,6 +136,8 @@ struct am_state {
 	int committer_date_is_author_date;
 	int ignore_date;
 	int allow_rerere_autoupdate;
+	int cover_at_tip;
+	int applying_cover;
 	const char *sign_commit;
 	int rebasing;
 };
@@ -160,6 +167,7 @@ static void am_state_init(struct am_state *state)
 
 	if (!git_config_get_bool("commit.gpgsign", &gpgsign))
 		state->sign_commit = gpgsign ? "" : NULL;
+
 }
 
 /**
@@ -432,6 +440,20 @@ static void am_load(struct am_state *state)
 	read_state_file(&sb, state, "utf8", 1);
 	state->utf8 = !strcmp(sb.buf, "t");
 
+	read_state_file(&sb, state, "cover-at-tip", 1);
+	state->cover_at_tip = !strcmp(sb.buf, "t");
+
+	if (state->cover_at_tip) {
+		read_state_file(&sb, state, "series_id", 1);
+		state->series_id = strtol(sb.buf, NULL, 10);
+
+		read_state_file(&sb, state, "series_len", 1);
+		state->series_len = strtol(sb.buf, NULL, 10);
+
+		read_state_file(&sb, state, "cover_id", 1);
+		state->cover_id = strtol(sb.buf, NULL, 10);
+	}
+
 	if (file_exists(am_path(state, "rerere-autoupdate"))) {
 		read_state_file(&sb, state, "rerere-autoupdate", 1);
 		state->allow_rerere_autoupdate = strcmp(sb.buf, "t") ?
@@ -1020,6 +1042,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
 	write_state_bool(state, "quiet", state->quiet);
 	write_state_bool(state, "sign", state->signoff);
 	write_state_bool(state, "utf8", state->utf8);
+	write_state_bool(state, "cover-at-tip", state->cover_at_tip);
 
 	if (state->allow_rerere_autoupdate)
 		write_state_bool(state, "rerere-autoupdate",
@@ -1076,6 +1099,12 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
 			delete_ref(NULL, "ORIG_HEAD", NULL, 0);
 	}
 
+	if (state->cover_at_tip) {
+		write_state_count(state, "series_id", state->series_id);
+		write_state_count(state, "series_len", state->series_len);
+		write_state_count(state, "cover_id", state->cover_id);
+	}
+
 	/*
 	 * NOTE: Since the "next" and "last" files determine if an am_state
 	 * session is in progress, they should be written last.
@@ -1088,13 +1117,9 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
 }
 
 /**
- * Increments the patch pointer, and cleans am_state for the application of the
- * next patch.
- */
-static void am_next(struct am_state *state)
+ * Cleans am_state.
+ */static void am_clean(struct am_state *state)
 {
-	struct object_id head;
-
 	FREE_AND_NULL(state->author_name);
 	FREE_AND_NULL(state->author_email);
 	FREE_AND_NULL(state->author_date);
@@ -1106,14 +1131,6 @@ static void am_next(struct am_state *state)
 
 	oidclr(&state->orig_commit);
 	unlink(am_path(state, "original-commit"));
-
-	if (!get_oid("HEAD", &head))
-		write_state_text(state, "abort-safety", oid_to_hex(&head));
-	else
-		write_state_text(state, "abort-safety", "");
-
-	state->cur++;
-	write_state_count(state, "next", state->cur);
 }
 
 /**
@@ -1274,6 +1291,7 @@ static int parse_mail(struct am_state *state, const char *mail)
 	fclose(mi.input);
 	fclose(mi.output);
 
+
 	/* Extract message and author information */
 	fp = xfopen(am_path(state, "info"), "r");
 	while (!strbuf_getline_lf(&sb, fp)) {
@@ -1298,9 +1316,30 @@ static int parse_mail(struct am_state *state, const char *mail)
 		goto finish;
 	}
 
-	if (is_empty_file(am_path(state, "patch"))) {
-		printf_ln(_("Patch is empty."));
-		die_user_resolve(state);
+	if (!state->applying_cover) {
+
+		state->series_id = mi.series_id;
+		state->series_len = mi.series_len;
+
+		if (state->cover_at_tip) {
+			write_state_count(state, "series_id", state->series_id);
+			write_state_count(state, "series_len", state->series_len);
+			write_state_count(state, "cover_id", state->cover_id);
+		}
+
+		if (mi.series_id == 0){
+			state->cover_id = state->cur;
+			ret = 1;
+			goto finish;
+		}
+
+		if (is_empty_file(am_path(state, "patch"))) {
+				printf_ln(_("Patch is empty."));
+				die_user_resolve(state);
+		} else if (state->cur == 1) {
+			/* First mail is not empty. cover-at-tip cannot apply */
+			state->cover_at_tip = 0;
+		}
 	}
 
 	strbuf_addstr(&msg, "\n\n");
@@ -1776,6 +1815,74 @@ static int do_interactive(struct am_state *state)
 	}
 }
 
+
+/**
+ * Apply the cover letter of a patch series
+ */
+static void do_apply_cover(struct am_state *state)
+{
+	int previous_cur = state->cur;
+	const char *mail;
+
+	am_clean(state);
+
+	state->cur = state->cover_id;
+	state->applying_cover = 1;
+	mail = am_path(state, msgnum(state));
+	if (!file_exists(mail))
+		die("BUG: cover has disapeared");
+
+	if(parse_mail(state, mail))
+		die("BUG: first patch is not a cover-letter");
+
+	if (state->signoff)
+		am_append_signoff(state);
+
+	write_author_script(state);
+	write_commit_msg(state);
+
+	if (state->interactive && do_interactive(state))
+		goto cancel_cover;
+
+	say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
+
+	do_commit(state);
+ cancel_cover:
+	state->cur = previous_cur;
+	state->applying_cover = 0;
+
+	/* Reset series metadata */
+	state->series_len = 0;
+	state->series_id = 0;
+	state->cover_id = 0;
+}
+
+/**
+ * Increments the patch pointer, and cleans am_state for the application of the
+ * next patch.
+ */
+static void am_next(struct am_state *state)
+{
+	struct object_id head;
+
+	/* Flush the cover letter if needed */
+	if (state->cover_at_tip == 1 &&
+	    state->series_len > 0 &&
+	    state->series_id == state->series_len &&
+	    state->cover_id > 0)
+		do_apply_cover(state);
+
+	am_clean(state);
+
+	if (!get_oid("HEAD", &head))
+		write_state_text(state, "abort-safety", oid_to_hex(&head));
+	else
+		write_state_text(state, "abort-safety", "");
+
+	state->cur++;
+	write_state_count(state, "next", state->cur);
+}
+
 /**
  * Applies all queued mail.
  *
@@ -2287,6 +2394,8 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 			N_("lie about committer date")),
 		OPT_BOOL(0, "ignore-date", &state.ignore_date,
 			N_("use current timestamp for author date")),
+		OPT_BOOL(0, "cover-at-tip", &state.cover_at_tip,
+			N_("apply cover letter to the tip of the branch")),
 		OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),
 		{ OPTION_STRING, 'S', "gpg-sign", &state.sign_commit, N_("key-id"),
 		  N_("GPG-sign commits"),
-- 
2.15.0.169.g3d3eebb67.dirty



  parent reply	other threads:[~2017-11-13 17:13 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-10 10:24 [RFC] cover-at-tip Nicolas Morey-Chaisemartin
2017-11-10 15:37 ` Nicolas Morey-Chaisemartin
2017-11-10 18:22   ` Junio C Hamano
2017-11-13  7:58     ` Nicolas Morey-Chaisemartin
2017-11-13  9:48       ` Junio C Hamano
2017-11-13 10:30         ` Junio C Hamano
2017-11-13 10:48           ` Nicolas Morey-Chaisemartin
2017-11-13 17:13           ` [RFC 0/3] Add support for --cover-at-tip Nicolas Morey-Chaisemartin
2017-11-13 19:40             ` Jonathan Tan
2017-11-13 19:53               ` Nicolas Morey-Chaisemartin
2017-11-13 17:13           ` [RFC 1/3] mailinfo: extract patch series id Nicolas Morey-Chaisemartin
2017-11-14  5:47             ` Junio C Hamano
2017-11-14  9:10               ` Nicolas Morey-Chaisemartin
2017-11-13 17:13           ` Nicolas Morey-Chaisemartin [this message]
2017-11-14  6:00             ` [RFC 2/3] am: semi working --cover-at-tip Junio C Hamano
2017-11-14  9:17               ` Nicolas Morey-Chaisemartin
2017-11-16 16:21                 ` Nicolas Morey-Chaisemartin
2017-11-17  1:54                   ` Junio C Hamano
2017-11-13 17:13           ` [RFC 3/3] log: add an option to generate cover letter from a branch tip Nicolas Morey-Chaisemartin
2017-11-14  6:14             ` Junio C Hamano
2017-11-14  9:28               ` Nicolas Morey-Chaisemartin
2017-11-14 13:05                 ` Junio C Hamano
2017-11-14 13:40                   ` Nicolas Morey-Chaisemartin
2017-11-14 14:52                     ` Junio C Hamano
2017-11-10 18:28   ` [RFC] cover-at-tip Jonathan 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=948b19c2-9f2d-de9d-1e0a-6681dc9317a9@suse.de \
    --to=nmoreychaisemartin@suse.de \
    --cc=git@vger.kernel.org \
    /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).