[PATCH RFC v2 02/16] sequencer: add option to rewind HEAD after picking commits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



While the sequencer infrastructure knows to rewind "HEAD" to whatever it
was pointing to before a rebase, it doesn't do the same for non-rebase
operations like cherry-picks. This is because the expectation is that
the user directly picks commits on top of whatever "HEAD" points to, and
we advance the reference pointed to by "HEAD" instead of updating it
directly.

We're about to introduce a new command though that needs to detach
"HEAD" while being more similar to git-cherry-pick(1) rathen than to
git-rebase(1). As such, we'll want to restore "HEAD" to point to the
branch that we started on while not using the more heavy-weight rebase
machinery.

Introduce a new option `restore_head_target` to do so. Persist the
option into the sequencer configuration so that it persists across
different processes, e.g. when we need to stop due to a merge conflict.

Signed-off-by: Patrick Steinhardt <ps@xxxxxx>
---
 sequencer.c | 27 ++++++++++++++++++++++++++-
 sequencer.h |  3 +++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/sequencer.c b/sequencer.c
index 7066cdc939..bff181df76 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -413,6 +413,7 @@ void replay_opts_release(struct replay_opts *opts)
 	struct replay_ctx *ctx = opts->ctx;
 
 	free(opts->gpg_sign);
+	free(opts->restore_head_target);
 	free(opts->reflog_action);
 	free(opts->default_strategy);
 	free(opts->strategy);
@@ -3142,6 +3143,8 @@ static int populate_opts_cb(const char *key, const char *value,
 	} else if (!strcmp(key, "options.skip-commit-summary")) {
 		opts->skip_commit_summary =
 			git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
+	} else if (!strcmp(key, "options.restore-head-target")) {
+		git_config_string_dup(&opts->restore_head_target, key, value);
 	} else {
 		return error(_("invalid key: %s"), key);
 	}
@@ -3709,6 +3712,10 @@ static int save_opts(struct replay_opts *opts)
 	if (opts->skip_commit_summary)
 		res |= repo_config_set_in_file_gently(the_repository, opts_file,
 					"options.skip-commit-summary", NULL, "true");
+	if (opts->restore_head_target)
+		res |= repo_config_set_in_file_gently(the_repository, opts_file,
+				"options.restore-head-target", NULL, opts->restore_head_target);
+
 	return res;
 }
 
@@ -5177,6 +5184,23 @@ static int pick_commits(struct repository *r,
 			return -1;
 	}
 
+	if (opts->restore_head_target) {
+		struct reset_head_opts reset_opts = { 0 };
+		const char *msg;
+
+		msg = reflog_message(opts, "finish", "returning to %s", opts->restore_head_target);
+
+		reset_opts.branch = opts->restore_head_target;
+		reset_opts.flags = RESET_HEAD_REFS_ONLY;
+		reset_opts.branch_msg = msg;
+		reset_opts.head_msg = msg;
+
+		if (reset_head(r, &reset_opts)) {
+			error(_("could not switch HEAD back to %s"), opts->restore_head_target);
+			return -1;
+		}
+	}
+
 	/*
 	 * Sequence of picks finished successfully; cleanup by
 	 * removing the .git/sequencer directory
@@ -5533,7 +5557,8 @@ int sequencer_pick_revisions(struct repository *r,
 	if (opts->revs->cmdline.nr == 1 &&
 	    opts->revs->cmdline.rev->whence == REV_CMD_REV &&
 	    opts->revs->no_walk &&
-	    !opts->revs->cmdline.rev->flags) {
+	    !opts->revs->cmdline.rev->flags &&
+	    !opts->restore_head_target) {
 		struct commit *cmit;
 
 		if (prepare_revision_walk(opts->revs)) {
diff --git a/sequencer.h b/sequencer.h
index 1767fd737e..a905f6afc7 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -72,6 +72,9 @@ struct replay_opts {
 	/* Reflog */
 	char *reflog_action;
 
+	/* Reference to which HEAD shall be reset to after the operation. */
+	char *restore_head_target;
+
 	/* placeholder commit for -i --root */
 	struct object_id squash_onto;
 	int have_squash_onto;

-- 
2.51.0.308.g032396e0da.dirty





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux