Hi Anders, On Mon, 8 Nov 2021, Anders Kaseorg wrote: > A bare repository won’t have a working tree at "..", but it may still > have separate working trees created with git worktree. We should protect > the current branch of such working trees from being updated or deleted, > according to receive.denyCurrentBranch. > > Signed-off-by: Anders Kaseorg <andersk@xxxxxxx> > --- > builtin/receive-pack.c | 4 +--- > t/t5516-fetch-push.sh | 12 ++++++++++++ > 2 files changed, 13 insertions(+), 3 deletions(-) > > diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c > index cf575280fc..5a3c6d8423 100644 > --- a/builtin/receive-pack.c > +++ b/builtin/receive-pack.c > @@ -1452,8 +1452,6 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w > const char *retval, *git_dir; > struct strvec env = STRVEC_INIT; > > - if (is_bare_repository()) > - return "denyCurrentBranch = updateInstead needs a worktree"; > git_dir = get_worktree_git_dir(worktree); > > strvec_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir)); > @@ -1476,7 +1474,7 @@ static const char *update(struct command *cmd, struct shallow_info *si) > struct object_id *old_oid = &cmd->old_oid; > struct object_id *new_oid = &cmd->new_oid; > int do_update_worktree = 0; > - const struct worktree *worktree = is_bare_repository() ? NULL : find_shared_symref("HEAD", name); > + const struct worktree *worktree = find_shared_symref("HEAD", name); While `find_shared_symref()` currently won't return a `worktree` with a non-zero `is_bare`, to future-proof the code we might want to turn the `if (worktree)` below (8 lines outside the current diff context) into `if (worktree && !worktree->is_bare)`. > > /* only refs/... are allowed */ > if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) { > diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh > index 2c2d6fa6e7..06cd34b0db 100755 > --- a/t/t5516-fetch-push.sh > +++ b/t/t5516-fetch-push.sh > @@ -1772,6 +1772,18 @@ test_expect_success 'denyCurrentBranch and worktrees' ' > test_must_fail git -C cloned push --delete origin new-wt > ' > > +test_expect_success 'denyCurrentBranch and bare repository worktrees' ' > + test_when_finished "rm -fr bare.git" && While `wt/` will be created inside `bare.git` and therefore be removed, the branch `wt` won't. Maybe add `&& git branch -D wt`? > + git clone --bare . bare.git && > + git -C bare.git worktree add wt && > + test_commit grape && I like fruit, too! Apple, banana, grape, yummy. I wonder what's next :-) > + test_config -C bare.git receive.denyCurrentBranch refuse && > + test_must_fail git push bare.git HEAD:wt && > + test_config -C bare.git receive.denyCurrentBranch updateInstead && > + git push bare.git HEAD:wt && Maybe make sure that `bare.git/wt/grape.t` exists? We do want the worktree to be updated, after all... Thanks, Dscho > + test_must_fail git push --delete bare.git wt > +' > + > test_expect_success 'refuse fetch to current branch of worktree' ' > test_when_finished "git worktree remove --force wt" && > git worktree add wt && > -- > 2.33.1 > >