git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org,
	"Philippe Blain" <levraiphilippeblain@gmail.com>,
	"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Elijah Newren" <newren@gmail.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"René Scharfe" <l.s.r@web.de>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Phillip Wood" <phillip.wood@dunelm.org.uk>
Subject: Re: [PATCH v2 03/14] rebase: pass correct arguments to post-checkout hook
Date: Thu, 09 Dec 2021 10:53:21 -0800	[thread overview]
Message-ID: <xmqqa6h9sj8e.fsf@gitster.g> (raw)
In-Reply-To: <07867760e68a6b28f718bdcb33094461592affaa.1638975482.git.gitgitgadget@gmail.com> (Phillip Wood via GitGitGadget's message of "Wed, 08 Dec 2021 14:57:50 +0000")

"Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> If a rebase started with "rebase [--apply|--merge] <upstream> <branch>"
> detects that <upstream> is an ancestor of <branch> then it fast-forwards
> and checks out <branch>. Unfortunately in that case it passed the null
> oid as the first argument to the post-checkout hook rather than the oid
> of HEAD.
>
> A side effect of this change is that the call to update_ref() which
> updates HEAD now always receives the old value of HEAD. This provides
> protection against another process updating HEAD during the checkout.

Nicely described.

> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> ---
>  reset.c                       | 18 +++++++++---------
>  t/t5403-post-checkout-hook.sh | 13 +++++++++++++
>  2 files changed, 22 insertions(+), 9 deletions(-)
>
> diff --git a/reset.c b/reset.c
> index f214df3d96c..315fef91d33 100644
> --- a/reset.c
> +++ b/reset.c
> @@ -18,7 +18,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
>  	unsigned run_hook = flags & RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
>  	unsigned refs_only = flags & RESET_HEAD_REFS_ONLY;
>  	unsigned update_orig_head = flags & RESET_ORIG_HEAD;
> -	struct object_id head_oid;
> +	struct object_id *head = NULL, head_oid;
>  	struct tree_desc desc[2] = { { NULL }, { NULL } };
>  	struct lock_file lock = LOCK_INIT;
>  	struct unpack_trees_options unpack_tree_opts = { 0 };
> @@ -26,8 +26,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
>  	const char *reflog_action;
>  	struct strbuf msg = STRBUF_INIT;
>  	size_t prefix_len;
> -	struct object_id *orig = NULL, oid_orig,
> -		*old_orig = NULL, oid_old_orig;
> +	struct object_id *old_orig = NULL, oid_old_orig;
>  	int ret = 0, nr = 0;
>  
>  	if (switch_to_branch && !starts_with(switch_to_branch, "refs/"))
> @@ -38,7 +37,9 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
>  		goto leave_reset_head;
>  	}
>  
> -	if ((!oid || !reset_hard) && get_oid("HEAD", &head_oid)) {
> +	if (!get_oid("HEAD", &head_oid)) {
> +		head = &head_oid;
> +	} else if (!oid || !reset_hard) {
>  		ret = error(_("could not determine HEAD revision"));
>  		goto leave_reset_head;
>  	}

Here, the original grabbed head_oid only when oid is not known or we
are not doing a hard reset.  Now we grab head_oid when available,
regardless of the other conditions.  But the logic to error out is
the same.  If oid is not given or not doing hard reset, it is an
error if we cannot figure out what object HEAD points at (is that
"unborn branch"?).

OK.


> @@ -98,13 +99,12 @@ reset_head_refs:
>  	if (update_orig_head) {
>  		if (!get_oid("ORIG_HEAD", &oid_old_orig))
>  			old_orig = &oid_old_orig;
> -		if (!get_oid("HEAD", &oid_orig)) {
> -			orig = &oid_orig;
> +		if (head) {
>  			if (!reflog_orig_head) {
>  				strbuf_addstr(&msg, "updating ORIG_HEAD");
>  				reflog_orig_head = msg.buf;
>  			}
> -			update_ref(reflog_orig_head, "ORIG_HEAD", orig,
> +			update_ref(reflog_orig_head, "ORIG_HEAD", head,
>  				   old_orig, 0, UPDATE_REFS_MSG_ON_ERR);
>  		} else if (old_orig)
>  			delete_ref(NULL, "ORIG_HEAD", old_orig, 0);

The variable 'orig' was initialized to NULL and then got assigned
the value of HEAD here, which is used in update_ref().  The new code
does the same thing with the 'head' variable that we have already
prepared earlier.  So there is no change here locally, but this
affects correctness later ...

> @@ -116,7 +116,7 @@ reset_head_refs:
>  		reflog_head = msg.buf;
>  	}
>  	if (!switch_to_branch)
> -		ret = update_ref(reflog_head, "HEAD", oid, orig,
> +		ret = update_ref(reflog_head, "HEAD", oid, head,
>  				 detach_head ? REF_NO_DEREF : 0,
>  				 UPDATE_REFS_MSG_ON_ERR);

... here.  In the original code, there is nothing that populates the
'orig' variable, if "update_orig_head" is not true, so we used to
pass NULL here.  Now as long as we know what HEAD is, we pass use it.



> @@ -128,7 +128,7 @@ reset_head_refs:
>  	}
>  	if (run_hook)
>  		run_hook_le(NULL, "post-checkout",
> -			    oid_to_hex(orig ? orig : null_oid()),
> +			    oid_to_hex(head ? head : null_oid()),

And the same fix is in effect here.

Nice.


> diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh
> index 272b02687ba..17ab518f268 100755
> --- a/t/t5403-post-checkout-hook.sh
> +++ b/t/t5403-post-checkout-hook.sh
> @@ -72,6 +72,19 @@ test_rebase () {
>  		test_cmp_rev rebase-on-me $new &&
>  		test $flag = 1
>  	'
> +
> +	test_expect_success "rebase $args fast-forward branch checkout runs post-checkout hook" '
> +		test_when_finished "test_might_fail git rebase --abort" &&
> +		test_when_finished "rm -f .git/post-checkout.args" &&
> +		git update-ref refs/heads/rebase-fast-forward three &&
> +		git checkout two  &&
> +		rm -f .git/post-checkout.args &&
> +		git rebase $args HEAD rebase-fast-forward  &&
> +		read old new flag <.git/post-checkout.args &&
> +		test_cmp_rev two $old &&
> +		test_cmp_rev three $new &&
> +		test $flag = 1
> +	'
>  }
>  
>  test_rebase --apply &&

  reply	other threads:[~2021-12-09 18:53 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-01 10:04 [PATCH 00/11] rebase: reset_head() related fixes and improvements Phillip Wood via GitGitGadget
2021-10-01 10:04 ` [PATCH 01/11] rebase: factor out checkout for up to date branch Phillip Wood via GitGitGadget
2021-10-01 10:04 ` [PATCH 02/11] reset_head(): fix checkout Phillip Wood via GitGitGadget
2021-10-01 20:26   ` Junio C Hamano
2021-10-04  9:58     ` Phillip Wood
2021-10-04 16:13       ` Junio C Hamano
2021-10-01 22:47   ` Eric Sunshine
2021-10-01 10:04 ` [PATCH 03/11] reset_head(): don't run checkout hook if there is an error Phillip Wood via GitGitGadget
2021-10-01 20:52   ` Junio C Hamano
2021-10-04 10:00     ` Phillip Wood
2021-10-12  8:48       ` Ævar Arnfjörð Bjarmason
2021-10-01 10:04 ` [PATCH 04/11] reset_head(): remove action parameter Phillip Wood via GitGitGadget
2021-10-01 20:58   ` Junio C Hamano
2021-10-04 10:00     ` Phillip Wood
2021-10-01 10:04 ` [PATCH 05/11] reset_head(): factor out ref updates Phillip Wood via GitGitGadget
2021-10-01 21:00   ` Junio C Hamano
2021-10-04 10:03     ` Phillip Wood
2021-10-01 10:04 ` [PATCH 06/11] reset_head(): make default_reflog_action optional Phillip Wood via GitGitGadget
2021-10-01 21:03   ` Junio C Hamano
2021-10-01 21:08   ` Junio C Hamano
2021-10-04 10:03     ` Phillip Wood
2021-10-01 10:04 ` [PATCH 07/11] rebase: cleanup reset_head() calls Phillip Wood via GitGitGadget
2021-10-01 10:04 ` [PATCH 08/11] reset_head(): take struct rebase_head_opts Phillip Wood via GitGitGadget
2021-10-01 21:11   ` Junio C Hamano
2021-10-04 10:09     ` Phillip Wood
2021-10-01 10:05 ` [PATCH 09/11] rebase --apply: fix reflog Phillip Wood via GitGitGadget
2021-10-01 21:12   ` Junio C Hamano
2021-10-01 10:05 ` [PATCH 10/11] rebase --apply: set ORIG_HEAD correctly Phillip Wood via GitGitGadget
2021-10-01 21:18   ` Junio C Hamano
2021-10-01 10:05 ` [PATCH 11/11] rebase -m: don't fork git checkout Phillip Wood via GitGitGadget
2021-10-02  0:38 ` [PATCH 00/11] rebase: reset_head() related fixes and improvements Junio C Hamano
2021-10-02  4:58   ` Junio C Hamano
2021-10-02 12:27     ` Phillip Wood
2021-10-02 13:12       ` Phillip Wood
2021-10-02 13:38       ` René Scharfe
2021-10-06 14:03         ` Phillip Wood
2021-12-08 14:57 ` [PATCH v2 00/14] " Phillip Wood via GitGitGadget
2021-12-08 14:57   ` [PATCH v2 01/14] rebase: factor out checkout for up to date branch Phillip Wood via GitGitGadget
2021-12-09 21:04     ` Junio C Hamano
2021-12-08 14:57   ` [PATCH v2 02/14] t5403: refactor rebase post-checkout hook tests Phillip Wood via GitGitGadget
2021-12-09 18:24     ` Junio C Hamano
2021-12-08 14:57   ` [PATCH v2 03/14] rebase: pass correct arguments to post-checkout hook Phillip Wood via GitGitGadget
2021-12-09 18:53     ` Junio C Hamano [this message]
2021-12-08 14:57   ` [PATCH v2 04/14] rebase: do not remove untracked files on checkout Phillip Wood via GitGitGadget
2021-12-09 19:09     ` Junio C Hamano
2021-12-08 14:57   ` [PATCH v2 05/14] rebase --apply: don't run post-checkout hook if there is an error Phillip Wood via GitGitGadget
2021-12-08 14:57   ` [PATCH v2 06/14] reset_head(): remove action parameter Phillip Wood via GitGitGadget
2021-12-08 14:57   ` [PATCH v2 07/14] create_autostash(): remove unneeded parameter Phillip Wood via GitGitGadget
2021-12-09 19:17     ` Junio C Hamano
2022-01-25 11:06       ` Phillip Wood
2021-12-08 14:57   ` [PATCH v2 08/14] reset_head(): factor out ref updates Phillip Wood via GitGitGadget
2021-12-08 14:57   ` [PATCH v2 09/14] reset_head(): make default_reflog_action optional Phillip Wood via GitGitGadget
2021-12-09 19:23     ` Junio C Hamano
2021-12-08 14:57   ` [PATCH v2 10/14] rebase: cleanup reset_head() calls Phillip Wood via GitGitGadget
2021-12-09 19:26     ` Junio C Hamano
2022-01-25 11:07       ` Phillip Wood
2021-12-08 14:57   ` [PATCH v2 11/14] reset_head(): take struct rebase_head_opts Phillip Wood via GitGitGadget
2021-12-09 19:31     ` Junio C Hamano
2021-12-08 14:57   ` [PATCH v2 12/14] rebase --apply: fix reflog Phillip Wood via GitGitGadget
2021-12-09 20:49     ` Junio C Hamano
2021-12-08 14:58   ` [PATCH v2 13/14] rebase --apply: set ORIG_HEAD correctly Phillip Wood via GitGitGadget
2021-12-11 10:59     ` Elijah Newren
2021-12-08 14:58   ` [PATCH v2 14/14] rebase -m: don't fork git checkout Phillip Wood via GitGitGadget
2021-12-09 21:04   ` [PATCH v2 00/14] rebase: reset_head() related fixes and improvements Junio C Hamano
2022-01-26 10:53     ` Phillip Wood
2022-01-27 17:37       ` Junio C Hamano
2021-12-11 11:05   ` Elijah Newren
2022-01-26 13:05   ` [PATCH v3 " Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 01/14] rebase: factor out checkout for up to date branch Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 02/14] t5403: refactor rebase post-checkout hook tests Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 03/14] rebase: pass correct arguments to post-checkout hook Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 04/14] rebase: do not remove untracked files on checkout Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 05/14] rebase --apply: don't run post-checkout hook if there is an error Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 06/14] reset_head(): remove action parameter Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 07/14] reset_head(): factor out ref updates Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 08/14] reset_head(): make default_reflog_action optional Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 09/14] create_autostash(): remove unneeded parameter Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 10/14] rebase: cleanup reset_head() calls Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 11/14] reset_head(): take struct rebase_head_opts Phillip Wood via GitGitGadget
2022-01-26 13:35       ` Ævar Arnfjörð Bjarmason
2022-01-26 14:52         ` Phillip Wood
2022-01-26 13:05     ` [PATCH v3 12/14] rebase --apply: fix reflog Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 13/14] rebase --apply: set ORIG_HEAD correctly Phillip Wood via GitGitGadget
2022-01-26 13:05     ` [PATCH v3 14/14] rebase -m: don't fork git checkout Phillip Wood via GitGitGadget
2022-02-01 17:03     ` [PATCH v3 00/14] rebase: reset_head() related fixes and improvements Elijah Newren

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=xmqqa6h9sj8e.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=l.s.r@web.de \
    --cc=levraiphilippeblain@gmail.com \
    --cc=newren@gmail.com \
    --cc=phillip.wood123@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=sunshine@sunshineco.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).