From: Junio C Hamano <gitster@pobox.com>
To: Anders Kaseorg <andersk@mit.edu>
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Jeff King <peff@peff.net>,
git@vger.kernel.org, Andreas Heiduk <andreas.heiduk@mathema.de>
Subject: Re: [PATCH v5 1/4] fetch: Protect branches checked out in all worktrees
Date: Wed, 10 Nov 2021 14:09:40 -0800 [thread overview]
Message-ID: <xmqqr1bnwtln.fsf@gitster.g> (raw)
In-Reply-To: <20211109230941.2518143-1-andersk@mit.edu> (Anders Kaseorg's message of "Tue, 9 Nov 2021 15:09:38 -0800")
Anders Kaseorg <andersk@mit.edu> writes:
> + if (!update_head_ok &&
> + (wt = find_shared_symref("HEAD", ref->name)) &&
> + !wt->is_bare &&
> !is_null_oid(&ref->old_oid)) {
> /*
> * If this is the head, and it's not okay to update
> * the head, and the old value of the head isn't empty...
> */
> format_display(display, '!', _("[rejected]"),
> - _("can't fetch in current branch"),
> + wt->is_current ?
> + _("can't fetch in current branch") :
> + _("checked out in another worktree"),
> remote, pretty_ref, summary_width);
> return 1;
> }
> @@ -1387,16 +1390,14 @@ 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;
> 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)) &&
> + !wt->is_bare)
> + die(_("Refusing to fetch into branch '%s' "
> + "checked out at '%s'"),
> + ref_map->peer_ref->name, wt->path);
> }
Another thing for the next development cycle.
The find_shared_symref() function is handy (and more correct than
dereferencing HEAD in the current worktree alone, of course), but
its memory ownership model may need to be rethought.
The current semantics is a caller can call find_shared_symref() to
receive at most one worktree, and the caller can use it UNTIL
anybody makes another call to find_shared_symref(), at which point,
the worktree instance becomes unusable and off limit. The caller
cannot, and should not attempt to, free the worktree instance.
Each time find_shared_symref() is called, we enumerate all the
worktrees and store them in a list that is static to the function.
The returned worktree instance points into that list. It is not
technically leaked because the static "worktrees" list in the
function holds onto it, and each time the function is called, the
old list of worktrees is discarded and rebuilt anew. What it means
is that a code like the above, a loop in check_not_current_branch(),
that repeatedly calls find_shared_symref() is both inefficient
(because it takes many "snapshots" of the worktrees attached to the
repository), and also risks an inconsistent view of the world
(because it takes many "snapshots", and each iteration uses
different ones).
I suspect that having a new API function that lets the above be
rewritten along the lines of ...
struct worktree **all = get_worktrees();
for ( ; ref_map; ref_map = ref_map->next) {
if (!ref_map->peer_ref)
continue;
wt = find_wt_with_HEAD(all, ref->map->peer_ref->name);
if (!wt->is_bare)
die(_("..."));
}
free_worktrees(all);
... would help.
Thanks.
next prev parent reply other threads:[~2021-11-10 22:11 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-08 20:16 [PATCH v3 2/2] receive-pack: Protect current branch for bare repository worktree Anders Kaseorg
2021-11-08 23:28 ` Junio C Hamano
2021-11-09 0:44 ` Junio C Hamano
2021-11-09 16:04 ` Johannes Schindelin
2021-11-09 1:10 ` Anders Kaseorg
2021-11-09 3:00 ` [PATCH v4 1/4] fetch: Protect branches checked out in all worktrees Anders Kaseorg
2021-11-09 3:00 ` [PATCH v4 2/4] receive-pack: Clean dead code from update_worktree() Anders Kaseorg
2021-11-09 16:16 ` Johannes Schindelin
2021-11-09 22:58 ` Anders Kaseorg
2021-11-09 3:00 ` [PATCH v4 3/4] receive-pack: Protect current branch for bare repository worktree Anders Kaseorg
2021-11-09 16:22 ` Johannes Schindelin
2021-11-09 23:03 ` Anders Kaseorg
2021-11-09 23:09 ` [PATCH v5 1/4] fetch: Protect branches checked out in all worktrees Anders Kaseorg
2021-11-09 23:09 ` [PATCH v5 2/4] receive-pack: Clean dead code from update_worktree() Anders Kaseorg
2021-11-10 3:57 ` Ævar Arnfjörð Bjarmason
2021-11-10 12:11 ` Johannes Schindelin
2021-11-09 23:09 ` [PATCH v5 3/4] receive-pack: Protect current branch for bare repository worktree Anders Kaseorg
2021-11-10 4:00 ` Ævar Arnfjörð Bjarmason
2021-11-09 23:09 ` [PATCH v5 4/4] branch: Protect branches checked out in all worktrees Anders Kaseorg
2021-11-10 4:03 ` Ævar Arnfjörð Bjarmason
2021-11-10 3:56 ` [PATCH v5 1/4] fetch: " Ævar Arnfjörð Bjarmason
2021-11-10 12:18 ` Johannes Schindelin
2021-11-10 23:46 ` Junio C Hamano
2021-11-11 0:11 ` Junio C Hamano
2021-11-10 22:09 ` Junio C Hamano [this message]
2021-11-10 23:33 ` Anders Kaseorg
2021-11-09 3:00 ` [PATCH v4 4/4] branch: " Anders Kaseorg
2021-11-09 16:24 ` Johannes Schindelin
2021-11-09 16:09 ` [PATCH v4 1/4] fetch: " Johannes Schindelin
2021-11-09 22:52 ` Anders Kaseorg
2021-11-09 23:00 ` Junio C Hamano
2021-11-09 23:28 ` Junio C Hamano
2021-11-09 23:32 ` Anders Kaseorg
2021-11-09 15:37 ` [PATCH v3 2/2] receive-pack: Protect current branch for bare repository worktree Johannes Schindelin
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqr1bnwtln.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=andersk@mit.edu \
--cc=andreas.heiduk@mathema.de \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/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.
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 NNTP newsgroup(s).