Subject: Re: [ANNOUNCE] Git v2.44.0

From: Patrick Steinhardt <[email-masked]>
Date: Sun, 25 Feb 2024 08:09:48 +0100

On Sun, Feb 25, 2024 at 04:55:50AM +0900, Mike Hommey wrote:
> On Sat, Feb 24, 2024 at 07:36:21AM +0100, Patrick Steinhardt wrote:
> > I have to wonder whether we ever
> > really specified what the environment of a remote helper should look
> > like when used during cloning. Conceptually it doesn't feel _wrong_ to
> > have a not-yet-initialized repo during clone.
> 
> How about this: it should look like what you'd get from
> `git init $repo`.

The problem is that it can't. With git-init(1) you already know how the
repo should look like as you specify parameters like SHA1 vs SHA256 via
parameters. But with git-clone(1) it's a different story, as you only
learn about how the repo should look like _after_ you have connected to
the remote. And thus, after you have executed the remote helper.

This has never been a problem with the old "files" backend because it
does not encode the object format in the refdb. But the "reftable"
backend does, and thus we can only creat the refdb after we have learned
about the object format. Future refdb implementations are likely to do
similar things.

> > Another idea would be to simply pre-create HEAD regardless of the ref
> > format, pointing to an invalid ref "refs/heads/.invalid". This is the
> > same trick we use for the reftable backend, and should likely address
> > your issue.
> 
> The interesting thing is that `git init $repo` does give you an invalid
> HEAD (and that's what would happen during git clone too), with either
> ```
> ref: refs/heads/master
> ```
> or
> ```
> ref: refs/heads/main
> ```
> depending on configuration.

HEAD in your example is not invalid, it's unborn. That's a difference
because creating the branch would succeed just fine. In the case of
"refs/heads/.invalid", creating the branch will fail because the ref
name would be refused.

With the reftable backend, we are forced to create HEAD exactly due to
the problem you have just encountered: a repo would not be discovered if
it did not exist. But its value shouldn't ever be read, because it is in
part of the reftables in "reftable/".

So as a safety mechanism, we want to make sure that the value of HEAD
cannot be interpreted like a "proper" ref. Clients that do not
understand the reftable format should not see a HEAD ref pointing to
"refs/heads/main" and then happily create or access such a branch.
That's why we want it to be an invalid ref.

That's ultimately the reason why I don't want HEAD to look like a proper
ref. But doing the "refs/heads/.invalid" workaround shouldn't be too bad,
I guess.

Patrick