diff mbox series

[v2,12/14] rebase --apply: fix reflog

Message ID dc5d11291e78bddde448f6e273bc58e9f2f83c95.1638975482.git.gitgitgadget@gmail.com (mailing list archive)
State Accepted
Commit 7700ab087b82f71d19134141045b95063e407344
Headers show
Series rebase: reset_head() related fixes and improvements | expand

Commit Message

Phillip Wood Dec. 8, 2021, 2:57 p.m. UTC
From: Phillip Wood <phillip.wood@dunelm.org.uk>

move_to_original_branch() passes the message intended for the branch
reflog as `orig_head_msg`. Fix this by adding a `branch_msg` member to
struct reset_head_opts and add a regression test.  Note that these
reflog messages do not respect GIT_REFLOG_ACTION. They are not alone
in that and will be fixed in a future series.

The "merge" backend already has tests that check both the branch and
HEAD reflogs.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
 builtin/rebase.c          |  8 ++++----
 reset.c                   | 12 ++++++++++--
 reset.h                   |  4 ++++
 t/t3406-rebase-message.sh | 23 +++++++++++++++++++++++
 4 files changed, 41 insertions(+), 6 deletions(-)

Comments

Junio C Hamano Dec. 9, 2021, 8:49 p.m. UTC | #1
"Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:

> +	if (opts->orig_head_msg && !update_orig_head)
> +		BUG("ORIG_HEAD reflog message given without updating ORIG_HEAD");
> +
> +	if (opts->branch_msg && !opts->branch)
> +		BUG("branch reflog message given without a branch");
> +

Looking pretty good.

> diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
> index 77a313f62eb..d17b450e811 100755
> --- a/t/t3406-rebase-message.sh
> +++ b/t/t3406-rebase-message.sh
> @@ -105,6 +105,29 @@ test_expect_success 'GIT_REFLOG_ACTION' '
>  	test_cmp expect actual
>  '
>  
> +test_expect_success 'rebase --apply reflog' '
> +	git checkout -b reflog-apply start &&
> +	old_head_reflog="$(git log -g --format=%gs -1 HEAD)" &&
> +
> +	git rebase --apply Y &&
> +
> +	git log -g --format=%gs -4 HEAD >actual &&
> +	cat >expect <<-EOF &&
> +	rebase finished: returning to refs/heads/reflog-apply
> +	rebase: Z
> +	rebase: checkout Y
> +	$old_head_reflog
> +	EOF
> +	test_cmp expect actual &&
> +
> +	git log -g --format=%gs -2 reflog-apply >actual &&
> +	cat >expect <<-EOF &&
> +	rebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)
> +	branch: Created from start
> +	EOF
> +	test_cmp expect actual
> +'
> +
>  test_expect_success 'rebase -i onto unrelated history' '
>  	git init unrelated &&
>  	test_commit -C unrelated 1 &&
diff mbox series

Patch

diff --git a/builtin/rebase.c b/builtin/rebase.c
index ecc368dd4f4..b55a9cff05d 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -570,7 +570,7 @@  static int finish_rebase(struct rebase_options *opts)
 
 static int move_to_original_branch(struct rebase_options *opts)
 {
-	struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
+	struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
 	struct reset_head_opts ropts = { 0 };
 	int ret;
 
@@ -580,17 +580,17 @@  static int move_to_original_branch(struct rebase_options *opts)
 	if (!opts->onto)
 		BUG("move_to_original_branch without onto");
 
-	strbuf_addf(&orig_head_reflog, "rebase finished: %s onto %s",
+	strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
 		    opts->head_name, oid_to_hex(&opts->onto->object.oid));
 	strbuf_addf(&head_reflog, "rebase finished: returning to %s",
 		    opts->head_name);
 	ropts.branch = opts->head_name;
 	ropts.flags = RESET_HEAD_REFS_ONLY;
-	ropts.orig_head_msg = orig_head_reflog.buf;
+	ropts.branch_msg = branch_reflog.buf;
 	ropts.head_msg = head_reflog.buf;
 	ret = reset_head(the_repository, &ropts);
 
-	strbuf_release(&orig_head_reflog);
+	strbuf_release(&branch_reflog);
 	strbuf_release(&head_reflog);
 	return ret;
 }
diff --git a/reset.c b/reset.c
index 78145d5c456..e02915c0f65 100644
--- a/reset.c
+++ b/reset.c
@@ -16,6 +16,7 @@  static int update_refs(const struct reset_head_opts *opts,
 	unsigned run_hook = opts->flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
 	unsigned update_orig_head = opts->flags & RESET_ORIG_HEAD;
 	const char *switch_to_branch = opts->branch;
+	const char *reflog_branch = opts->branch_msg;
 	const char *reflog_head = opts->head_msg;
 	const char *reflog_orig_head = opts->orig_head_msg;
 	const char *default_reflog_action = opts->default_reflog_action;
@@ -58,8 +59,9 @@  static int update_refs(const struct reset_head_opts *opts,
 				 detach_head ? REF_NO_DEREF : 0,
 				 UPDATE_REFS_MSG_ON_ERR);
 	else {
-		ret = update_ref(reflog_head, switch_to_branch, oid,
-				 NULL, 0, UPDATE_REFS_MSG_ON_ERR);
+		ret = update_ref(reflog_branch ? reflog_branch : reflog_head,
+				 switch_to_branch, oid, NULL, 0,
+				 UPDATE_REFS_MSG_ON_ERR);
 		if (!ret)
 			ret = create_symref("HEAD", switch_to_branch,
 					    reflog_head);
@@ -90,6 +92,12 @@  int reset_head(struct repository *r, const struct reset_head_opts *opts)
 	if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
 		BUG("Not a fully qualified branch: '%s'", switch_to_branch);
 
+	if (opts->orig_head_msg && !update_orig_head)
+		BUG("ORIG_HEAD reflog message given without updating ORIG_HEAD");
+
+	if (opts->branch_msg && !opts->branch)
+		BUG("branch reflog message given without a branch");
+
 	if (!refs_only && repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
 		ret = -1;
 		goto leave_reset_head;
diff --git a/reset.h b/reset.h
index a205be2fb85..7ef7e43ea8c 100644
--- a/reset.h
+++ b/reset.h
@@ -30,6 +30,10 @@  struct reset_head_opts {
 	 * Flags defined above.
 	 */
 	unsigned flags;
+	/*
+	 * Optional reflog message for branch, defaults to head_msg.
+	 */
+	const char *branch_msg;
 	/*
 	 * Optional reflog message for HEAD, if this omitted but oid or branch
 	 * are given then default_reflog_action must be given.
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 77a313f62eb..d17b450e811 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -105,6 +105,29 @@  test_expect_success 'GIT_REFLOG_ACTION' '
 	test_cmp expect actual
 '
 
+test_expect_success 'rebase --apply reflog' '
+	git checkout -b reflog-apply start &&
+	old_head_reflog="$(git log -g --format=%gs -1 HEAD)" &&
+
+	git rebase --apply Y &&
+
+	git log -g --format=%gs -4 HEAD >actual &&
+	cat >expect <<-EOF &&
+	rebase finished: returning to refs/heads/reflog-apply
+	rebase: Z
+	rebase: checkout Y
+	$old_head_reflog
+	EOF
+	test_cmp expect actual &&
+
+	git log -g --format=%gs -2 reflog-apply >actual &&
+	cat >expect <<-EOF &&
+	rebase finished: refs/heads/reflog-apply onto $(git rev-parse Y)
+	branch: Created from start
+	EOF
+	test_cmp expect actual
+'
+
 test_expect_success 'rebase -i onto unrelated history' '
 	git init unrelated &&
 	test_commit -C unrelated 1 &&