git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: Anders Kaseorg <andersk@mit.edu>
Cc: Junio C Hamano <gitster@pobox.com>,
	git@vger.kernel.org, Andreas Heiduk <andreas.heiduk@mathema.de>
Subject: Re: [PATCH v2] fetch: Protect branches checked out in all worktrees
Date: Fri, 5 Nov 2021 04:38:13 -0400	[thread overview]
Message-ID: <YYTtdZblnHYgDgBq@coredump.intra.peff.net> (raw)
In-Reply-To: <alpine.DEB.2.21.999.2111041709080.94135@tardis-on-the-dome.mit.edu>

On Thu, Nov 04, 2021 at 05:10:52PM -0400, Anders Kaseorg wrote:

> Refuse to fetch into the currently checked out branch of any working
> tree, not just the current one.

I think that makes sense as a goal.

>  #define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000)
>  
> @@ -854,7 +855,6 @@ static int update_local_ref(struct ref *ref,
>  			    int summary_width)
>  {
>  	struct commit *current = NULL, *updated;
> -	struct branch *current_branch = branch_get(NULL);
>  	const char *pretty_ref = prettify_refname(ref->name);
>  	int fast_forward = 0;
>  
> @@ -868,9 +868,8 @@ static int update_local_ref(struct ref *ref,
>  		return 0;
>  	}
>  
> -	if (current_branch &&
> -	    !strcmp(ref->name, current_branch->name) &&
> -	    !(update_head_ok || is_bare_repository()) &&
> +	if (!update_head_ok &&
> +	    find_shared_symref("HEAD", ref->name) &&
>  	    !is_null_oid(&ref->old_oid)) {
>  		/*
>  		 * If this is the head, and it's not okay to update

OK, so this is where we'd say "no, I won't update the HEAD". That makes
sense, and the find_shared_symref() helper from worktree.h makes it
easy.

If we get the non-default worktree here, it might be nice to tell the
user which worktree has it checked out. Otherwise it may lead to
head-scratching as they peek at their current HEAD.

I also notice that find_shared_symref() will catch cases where we're on
a detached HEAD, but it's because we're rebasing or bisecting on a given
branch. Arguably that's a sensible thing to do for this check, but it is
a change from the current behavior (even if you are not using worktrees
at all).

> @@ -1387,16 +1386,13 @@ static int prune_refs(struct refspec *rs, struct ref *ref_map,
>  
>  static void check_not_current_branch(struct ref *ref_map)
>  {
> -	struct branch *current_branch = branch_get(NULL);
> -
> -	if (is_bare_repository() || !current_branch)
> -		return;
> -
> +	const struct worktree *wt;
> [...]

So if the earlier hunk covered this case, then what is this hunk for? :)

It looks like we call it from do_fetch() when update_head_ok isn't set.
I'm not clear why we have two distinct code paths that check
update_head_ok. It seems like this one is the one that _actually_ kicks
in, because it's only later that we call update_local_ref(), several
layers down. If I put a BUG() in that one, it is never reached in the
test suite. Hmm.

It looks like this situation is quite old, and certainly it's nothing
new in your patch. So let's file it as a curiosity for now, and we can
deal with it separately (if at all).

>  	for (; ref_map; ref_map = ref_map->next)
> -		if (ref_map->peer_ref && !strcmp(current_branch->refname,
> -					ref_map->peer_ref->name))
> -			die(_("Refusing to fetch into current branch %s "
> -			    "of non-bare repository"), current_branch->refname);
> +		if (ref_map->peer_ref &&
> +		    (wt = find_shared_symref("HEAD", ref_map->peer_ref->name)))
> +			die(_("Refusing to fetch into branch '%s' "
> +			      "checked out at '%s'"),
> +			    ref_map->peer_ref->name, wt->path);

This one does update the message, which is nice (and from my analysis
above, the message from the other hunk doesn't matter at all!). It's a
bit more verbose if you're not using worktrees at all, though. I used to get:

  $ git init
  $ git commit --allow-empty -qm foo
  $ git fetch . main:main
  fatal: Refusing to fetch into current branch refs/heads/main of non-bare repository

but now get:

  $ git fetch . main:main
  fatal: Refusing to fetch into branch 'refs/heads/main' checked out at '/home/peff/tmp'

It's technically correct, but perhaps it would be nicer to keep the old
message if the worktree we found is the current one.

-Peff

  reply	other threads:[~2021-11-05  8:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-04 21:05 [PATCH] fetch: Protect branches checked out in all worktrees Anders Kaseorg
2021-11-04 21:10 ` [PATCH v2] " Anders Kaseorg
2021-11-05  8:38   ` Jeff King [this message]
2021-11-05 10:01     ` Anders Kaseorg
2021-11-05 11:53       ` Jeff King
2021-11-05 18:39         ` Junio C Hamano
2021-11-08 20:12         ` Anders Kaseorg

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=YYTtdZblnHYgDgBq@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=andersk@mit.edu \
    --cc=andreas.heiduk@mathema.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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).