On 12/18/21 11:46 AM, Sean Allred wrote:
What did you do before the bug happened? (Steps to reproduce your issue) ~$ git clone --bare https://github.com/git/git.git ~/gitbare$ git config --list --show-origin file:config core.bare=true ~/gitbare$ git worktree add --no-checkout ../next Preparing worktree (checking out 'next') ~/gitbare$ git config --list --show-origin file:config core.bare=true ~/gitbare$ cd ../next/ ~/next$ git config --list --show-origin file:../gitbare/config core.bare=true ~/next$ git rev-parse --is-bare-repository false ~/next$ git config extensions.worktreeconfig true ~/next$ git rev-parse --is-bare-repository true ~/next$ git config --unset extensions.worktreeconfig ~/next$ git rev-parse --is-bare-repository false
As far as I can tell, this is working as designed and as documented[1]. `git rev-parse --is-bare-repository` is supposed to return "true" in the bare repository, and "false" in a worktree. However, you missed the step (discussed in [1]) in which it is your responsibility to move the `core.bare=true` setting from git.git/config to git.git/worktree.config manually after setting `extensions.worktreeconfig=true`.
When `extensions.worktreeconfig` is false, --is-bare-repository special cases `core.bare` to return "false" in a worktree regardless of the setting in git.git/config. When `extensions.worktreeconfig` is true, however, that special-casing behavior is disabled, and --is-bare-repository returns whatever it pulls from the configuration. In this case, it returned the value of `core.bare` from git.git/config since you hadn't moved `core.bare=true` to git.git/worktree.config, which would be local only to the bare repository, and not seen by any worktrees.
[1]: https://git-scm.com/docs/git-worktree#_configuration_file
I actually found this situation (and narrowed it to the above) by trying to perform a sparse-checkout in the worktree. It appears sparse-checkout by default uses a worktree-specific config (which does make sense). What did you expect to happen? (Expected behavior) I expected one of the following to happen: 1. I should have been blocked from creating a worktree from a bare repository. 2. is_bare_repository() shouldn't be fooled by this situation, assuming it's valid. All things being equal, I would more expect to have been blocked from creating a worktree from a bare repository. Personally, this bare repo + worktree setup doesn't not align with my experience so far with how bare repos are normally used (i.e., as a convenience for centralized remotes that will never be doing a checkout).
Regarding #1, creating worktrees from a bare repository is an explicitly-supported use-case, and we've heard several times on the mailing list from people who take advantage of the ability in automation situations (often in CI setups), as well as from people who use it as a part of their daily workflow (in which they don't consider any particular worktree to be "blessed").
Regarding #2, --is-bare-repository is not so much being fooled as it is being lied to by your configuration which wasn't updated to move `core.bare=true` to git.git/worktree.config. (Granted, it's painful that it's your responsibility to move the setting manually; automating would avoid this sort of confusion.)
What happened instead? (Actual behavior) is_bare_repository() is fooled and I'm prevented from performing any operation that requires a worktree (like performing a sparse checkout). What's different between what you expected and what actually happened? is_bare_repository() is fooled into thinking the worktree is not a worktree / I'm able to create a worktree from a bare repo.