Re: [ANNOUNCE] Git v2.44.0
From: Mike Hommey <hidden>
Date: 2024-02-24 19:56:05
On Sat, Feb 24, 2024 at 07:36:21AM +0100, Patrick Steinhardt wrote:
Thanks for your report!
This has to be because we now initialize the refdb at a later point. The
problem here was that before my change, we initialized the refdb at a
point when it wasn't clear what the remote actually used as the object
format. The consequence was twofold:
- Cloning a repository with bundles was broken in case the remote uses
the SHA256 object format.
- Cloning into a repository that uses reftables when the remote uses
the SHA256 object format was broken, too.
Both of these have the same root cause: because we didn't connect to the
remote yet we had no idea what object format the remote uses. And as we
initialized the refdb early, it was then initialized with the default
object format, which is SHA1.
The change was to move initialization of the refdb to a later point in
time where we know what object format the remote uses. By necessity,
this has to be _after_ we have connected to the remote, because there is
no way to learn about it without connecting to it.
One consequence of initializing the refdb at a later point in time is
that we have no "HEAD" yet, and a repo without the "HEAD" file is not
considered to be a repo. Thus, git-config(1) would now rightfully fail.
I assume that you discovered it via a remote helper that does something
more interesting than git-config(1).Indeed, my own usecase is a remote helper that uses libgit.a and uses is_git_directory indirectly, but I could imagine other remote helpers that could be using other git commands that rely on is_git_directory returning true.
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`.
But on the other hand, regressing functionality like this is of course bad. I was wondering whether we can get around this issue by setting e.g. GIT_DIR explicitly when spawning the remote helper, but I don't think it's as easy as that.
GIT_DIR is already set when spawning the remote helper. My remote helper is using setup_git_directory_gently and uses the value of nongit_ok for the cases where the executable is used without being wrapped by git (it provides extra commands), I guess I could use whether GIT_DIR is set as a workaround.
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. Mike