Re: [PATCH v4 3/4] receive-pack: Protect current branch for bare repository worktree
From: Johannes Schindelin <hidden>
Date: 2021-11-09 16:22:59
Hi Anders, On Mon, 8 Nov 2021, Anders Kaseorg wrote:
quoted hunk ↗ jump to hunk
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 <redacted> --- 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)`.
quoted hunk ↗ jump to hunk
/* 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