Subject: Re: Testing for existence of a remote branch from a script

From: Junio C Hamano <[email-masked]>
Date: Mon, 06 Jan 2025 07:30:32 -0800

Torsten Bögershausen <[email-masked]> writes:

>> changes are fetched from one branch (e.g. 'foo') but are pushed to a
>> different one ('foo_incoming'). Our CI system runs to test the changes
>> and when they pass 'foo_incoming' is merged (fast-forward most of the
>> time) into 'foo'.
>> ...
>> Is there a better way of checking for the existence of a remote branch?
>
> I may have missed something, would that work:
> git fetch -p
> git branch -r

Or "git ls-remote origin refs/heads/foo-incoming" and see if it
yields anything?

The "workflow" makes me wonder how it would be bootstrapped, though.

When you add a new branch, "bar", to be pre-reviewed before getting
merged at the server side, you want people to push to
"bar-incoming".  Before the very initial update to "bar-incoming"
that pushes into "bar-incoming" and creates it, there wouldn't be
"bar-incoming" on the remote side, would there?  So "see if
foo-incoming exists and change the behaviour on the client end
accordingly" may not be a strategy to pursue.

If we wanted to support the "workflow" natively, the way we would do
so would be to introduce a protocol capability that allows the
server side to advertise:

    If you want to update branch B, you are not allowed to do so
    directly.  Instead, you are expected to push your changes to
    update 'refs/for/B'

and then "git push" on the client end would notice the capability
and turns "git push origin B" (or, more likely, the user is on local
branch B that is to build on the remote branch B from 'origin', and
"git push" with no arguments would do the right thing) into such an
update.

I am not suggesting that we jump to the above immediately.  But the
reason why I am bringing it up is because The "how would I see if
they have foo-incoming?" smells like seeking a way to implement such
a custom capability advertisement outside Git.

A few random thoughts.

 - Would it be useful if we introduced the ability to advertise
   "custom capabilities" from the receiving end of the connection,
   that does not affect how the rest of Git behaves at all?  It
   would be sort of the reverse of --server-option, which is a
   mechanism to let the client to tell the other side out of band
   information that the rest of Git is oblivious.

   The other side of course needs a way to inspect what capabilities
   are advertised.  For "--server-option", I do not think our server
   end does anything special, but other implementations can act on
   them.  This new thing can start the same way.

 - If this is a poor-man's custom capability advertisement, perhaps
   the server end can create a ref "refs/capabilities/incoming"
   (whose value does not really matter) and your client side can see
   if there is such a ref with "ls-remote"?  That may be a more
   robust thing to do instead, perhaps, as you do not need to worry
   about "What about a new branch 'bar'?" bootstrapping issues.