Re: [PATCH v4 3/4] receive-pack: Protect current branch for bare repository worktree
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Nov 9, 2021, 16:22 UTC
- Message-ID
- <nycvar.QRO.7.76.6.2111091717230.54@tvgsbejvaqbjf.bet>
- In-Reply-To
- <20211109030028.2196416-3-andersk@mit.edu>
Hi Anders,
On Mon, 8 Nov 2021, Anders Kaseorg wrote:
Show 30 quoted lines
> 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>
> ---
> 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)`.
Show 13 quoted lines
>
> /* 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
Show 10 quoted lines
> + 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 > >