Add 'promisor-remote' capability to protocol v2

When a server S knows that some objects from a repository are available
from a promisor remote X, S might want to suggest to a client C cloning
or fetching the repo from S that C may use X directly instead of S for
these objects.

Note that this could happen both in the case S itself doesn't have the
objects and borrows them from X, and in the case S has the objects but
knows that X is better connected to the world (e.g., it is in a
$LARGEINTERNETCOMPANY datacenter with petabit/s backbone connections)
than S. Implementation of the latter case, which would require S to
omit in its response the objects available on X, is left for future
improvement though.

Then C might or might not, want to get the objects from X. If S and C
can agree on C using X directly, S can then omit objects that can be
obtained from X when answering C's request.

To allow S and C to agree and let each other know about C using X or
not, let's introduce a new "promisor-remote" capability in the
protocol v2, as well as a few new configuration variables:

  - "promisor.advertise" on the server side, and:
  - "promisor.acceptFromServer" on the client side.

By default, or if "promisor.advertise" is set to 'false', a server S will
not advertise the "promisor-remote" capability.

If S doesn't advertise the "promisor-remote" capability, then a client C
replying to S shouldn't advertise the "promisor-remote" capability
either.

If "promisor.advertise" is set to 'true', S will advertise its promisor
remotes with a string like:

  promisor-remote=<pr-info>[;<pr-info>]...

where each <pr-info> element contains information about a single
promisor remote in the form:

  name=<pr-name>[,url=<pr-url>]

where <pr-name> is the urlencoded name of a promisor remote and
<pr-url> is the urlencoded URL of the promisor remote named <pr-name>.

For now, the URL is passed in addition to the name. In the future, it
might be possible to pass other information like a filter-spec that the
client may use when cloning from S, or a token that the client may use
when retrieving objects from X.

It is C's responsibility to arrange how it can reach X though, so pieces
of information that are usually outside Git's concern, like proxy
configuration, must not be distributed over this protocol.

It might also be possible in the future for "promisor.advertise" to have
other values. For example a value like "onlyName" could prevent S from
advertising URLs, which could help in case C should use a different URL
for X than the URL S is using. (The URL S is using might be an internal
one on the server side for example.)

By default or if "promisor.acceptFromServer" is set to "None", C will
not accept to use the promisor remotes that might have been advertised
by S. In this case, C will not advertise any "promisor-remote"
capability in its reply to S.

If "promisor.acceptFromServer" is set to "All" and S advertised some
promisor remotes, then on the contrary, C will accept to use all the
promisor remotes that S advertised and C will reply with a string like:

  promisor-remote=<pr-name>[;<pr-name>]...

where the <pr-name> elements are the urlencoded names of all the
promisor remotes S advertised.

In a following commit, other values for "promisor.acceptFromServer" will
be implemented, so that C will be able to decide the promisor remotes it
accepts depending on the name and URL it received from S. So even if
that name and URL information is not used much right now, it will be
needed soon.

Helped-by: Taylor Blau <me@ttaylorr.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Christian Couder
2025-02-18 12:32:02 +01:00
committed by Junio C Hamano
parent 0394451348
commit d460267613
9 changed files with 584 additions and 1 deletions

View File

@ -781,6 +781,60 @@ retrieving the header from a bundle at the indicated URI, and thus
save themselves and the server(s) the request(s) needed to inspect the
headers of that bundle or bundles.
promisor-remote=<pr-infos>
~~~~~~~~~~~~~~~~~~~~~~~~~~
The server may advertise some promisor remotes it is using or knows
about to a client which may want to use them as its promisor remotes,
instead of this repository. In this case <pr-infos> should be of the
form:
pr-infos = pr-info | pr-infos ";" pr-info
pr-info = "name=" pr-name | "name=" pr-name "," "url=" pr-url
where `pr-name` is the urlencoded name of a promisor remote, and
`pr-url` the urlencoded URL of that promisor remote.
In this case, if the client decides to use one or more promisor
remotes the server advertised, it can reply with
"promisor-remote=<pr-names>" where <pr-names> should be of the form:
pr-names = pr-name | pr-names ";" pr-name
where `pr-name` is the urlencoded name of a promisor remote the server
advertised and the client accepts.
Note that, everywhere in this document, `pr-name` MUST be a valid
remote name, and the ';' and ',' characters MUST be encoded if they
appear in `pr-name` or `pr-url`.
If the server doesn't know any promisor remote that could be good for
a client to use, or prefers a client not to use any promisor remote it
uses or knows about, it shouldn't advertise the "promisor-remote"
capability at all.
In this case, or if the client doesn't want to use any promisor remote
the server advertised, the client shouldn't advertise the
"promisor-remote" capability at all in its reply.
The "promisor.advertise" and "promisor.acceptFromServer" configuration
options can be used on the server and client side to control what they
advertise or accept respectively. See the documentation of these
configuration options for more information.
Note that in the future it would be nice if the "promisor-remote"
protocol capability could be used by the server, when responding to
`git fetch` or `git clone`, to advertise better-connected remotes that
the client can use as promisor remotes, instead of this repository, so
that the client can lazily fetch objects from these other
better-connected remotes. This would require the server to omit in its
response the objects available on the better-connected remotes that
the client has accepted. This hasn't been implemented yet though. So
for now this "promisor-remote" capability is useful only when the
server advertises some promisor remotes it already uses to borrow
objects from.
GIT
---
Part of the linkgit:git[1] suite