]> git.ipfire.org Git - thirdparty/git.git/commitdiff
receive-pack: protect current branch for bare repository worktree
authorAnders Kaseorg <andersk@mit.edu>
Wed, 1 Dec 2021 22:15:46 +0000 (14:15 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Dec 2021 06:18:25 +0000 (22:18 -0800)
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@mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/receive-pack.c
t/t5516-fetch-push.sh

index 29dc0e56f74c7dede45250cfb31bb816d48ac6d5..26ecaa5cd55dcdfddf410edbf28775e3bfea0f95 100644 (file)
@@ -1455,7 +1455,7 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w
        if (!worktree || !worktree->path)
                BUG("worktree->path must be non-NULL");
 
-       if (is_bare_repository())
+       if (worktree->is_bare)
                return "denyCurrentBranch = updateInstead needs a worktree";
        git_dir = get_worktree_git_dir(worktree);
 
@@ -1481,9 +1481,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
        int do_update_worktree = 0;
        struct worktree **worktrees = get_worktrees();
        const struct worktree *worktree =
-               is_bare_repository() ?
-                       NULL :
-                       find_shared_symref(worktrees, "HEAD", name);
+               find_shared_symref(worktrees, "HEAD", name);
 
        /* only refs/... are allowed */
        if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
@@ -1496,7 +1494,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
        free(namespaced_name);
        namespaced_name = strbuf_detach(&namespaced_name_buf, NULL);
 
-       if (worktree) {
+       if (worktree && !worktree->is_bare) {
                switch (deny_current_branch) {
                case DENY_IGNORE:
                        break;
index f07e32126fced4a3f26bc10f3910f862359cb9d2..cd2e144c372ebe3dc2400df32b025a9ce5b4f750 100755 (executable)
@@ -1769,9 +1769,23 @@ test_expect_success 'denyCurrentBranch and worktrees' '
        test_must_fail git -C cloned push origin HEAD:new-wt &&
        test_config receive.denyCurrentBranch updateInstead &&
        git -C cloned push origin HEAD:new-wt &&
+       test_path_exists new-wt/first.t &&
        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" &&
+       git clone --bare . bare.git &&
+       git -C bare.git worktree add wt &&
+       test_commit grape &&
+       git -C bare.git config receive.denyCurrentBranch refuse &&
+       test_must_fail git push bare.git HEAD:wt &&
+       git -C bare.git config receive.denyCurrentBranch updateInstead &&
+       git push bare.git HEAD:wt &&
+       test_path_exists bare.git/wt/grape.t &&
+       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 branch -D wt" &&
        git worktree add wt &&