Subject: Re: git remote set-head automatically

From: "Bence Ferdinandy" <[email-masked]>
Date: Sat, 16 Nov 2024 16:01:59 +0100

On Sat Nov 16, 2024 at 04:36, Jeff King <[email-masked]> wrote:
> On Fri, Nov 15, 2024 at 09:34:28AM -0500, Caleb Cushing wrote:
>
>> Context: recently I've been trying to develop a feature for my Gradle
>> plugin that derives a semantic version from git describe.  In order to
>> achieve my next level of feature I need the HEAD Branch. Now, I can
>> get this branch using git remote show <remote> and parsing the output.
>> I'm a firm believer that it should be possible for me to write code,
>> long term even, without the internet; I did this once with my job when
>> I needed to go home to my parents who were very rural and didn't have
>> internet; I was able to keep working without access. I want that for
>> anyone that uses this tool.
>
> You should use the refs/remotes/<remote>/HEAD symref instead (or its
> alias, just "<remote>"), which is more convenient and doesn't hit the
> network. Which is exactly what...
>
>> Problem: I don't want to have to do a network request every time I do
>> a build, in fact I'd rather almost never have to do a network request.
>> Gradle makes reducing the network request to less than once per build
>> something ... unsupported. jgit doesn't expose support for fetching
>> this information. Then I found out that you could do `git remote
>> set-head <remote> <branch>` which appears to behave exactly how I'd
>> want and expect. It doesn't easily solve my problem though because I
>> want my solution to be generally applicable.
>
> ...set-head will set. So OK, but...
>
>> Ideal Long-Term Solution: git remote set-head happens automatically on
>> lone, and even fetch if it's not set. Explicit setting would override
>> any automatic setting; and it might be a good idea to automatically
>> unset if the HEAD branch disappears from the remote.
>
> We already do the equivalent of set-head on clone. If you do:
>
>   git clone https://github.com/git/git
>   cd git
>   git symbolic-ref refs/remotes/origin/HEAD
>
> you should see it pointing to "refs/remotes/origin/master" (and like you
> can refer to "origin/HEAD" or "origin" from git-log, etc). Are you not
> seeing that?
>
> We don't update it on fetch. That has been discussed, but there are some
> questions about when it should overwrite what's available locally. E.g.
> this thread:
>
>   https://lore.kernel.org/git/[email-masked]/

That part we already have pinned down: fetch will only update remote/HEAD if it
doesn't already exist. So running "init && remote add && fetch" should end you
up in the same place as "clone" (although fetch will report if the remote has
changed HEAD compared to what you have for transparency). If you _always_ want
to have the latest head you'll need to run "fetch && remote set-head --auto
[remote]" every time.

Something like
	git fetch --all && git remote | xargs -i git remote set-head -a {}
covers everything.

>
> There have been some patches in that direction but I have not kept up
> with the current state:
>
>   https://lore.kernel.org/git/[email-masked]/

There's definitely going to be another round, but I think (hope :)) we're not
very far off from finishing.

Best,
Bence