Reputation: 43
If I clone a repo using protocol v0, and v2, everything is ok. but if I change the protocol to v1, I got this:
$GIT_TRACE_PACKET=1 git clone -c protocol.version=1 https://gitee.com/yomorun/yomo.git out
Cloning into 'out'...
16:57:10.089707 pkt-line.c:80 packet: git< version 1
fatal: invalid server response; got 'version 1'
The error message comes from check_smart_http() method, I know that protocol v2, and v0 are all smart protocol, but isn't v1 smart protocol the same?
Here I post a source code snippet of Git:
static void check_smart_http(struct discovery *d, const char *service,
struct strbuf *type)
{
const char *p;
struct packet_reader reader;
warning(" remote-curl.c call [check_smart_http]");
/*
* If we don't see x-$service-advertisement, then it's not smart-http.
* But once we do, we commit to it and assume any other protocol
* violations are hard errors.
*/
if (!skip_prefix(type->buf, "application/x-", &p) ||
!skip_prefix(p, service, &p) ||
strcmp(p, "-advertisement"))
return;
packet_reader_init(&reader, -1, d->buf, d->len,
PACKET_READ_CHOMP_NEWLINE |
PACKET_READ_DIE_ON_ERR_PACKET);
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
die(_("invalid server response; expected service, got flush packet"));
if (skip_prefix(reader.line, "# service=", &p) && !strcmp(p, service)) {
/*
* The header can include additional metadata lines, up
* until a packet flush marker. Ignore these now, but
* in the future we might start to scan them.
*/
for (;;) {
packet_reader_read(&reader);
if (reader.pktlen <= 0) {
break;
}
}
/*
* v0 smart http; callers expect us to soak up the
* service and header packets
*/
d->buf = reader.src_buffer;
d->len = reader.src_len;
d->proto_git = 1;
} else if (!strcmp(reader.line, "version 2")) {
/*
* v2 smart http; do not consume version packet, which will
* be handled elsewhere.
*/
d->proto_git = 1;
} else {
die(_("invalid server response; got '%s'"), reader.line);
}
}
I don't figure out why it ignored version 1.
Upvotes: 4
Views: 2741
Reputation: 1327384
The "protocol v1" was introduced in commit aa9bab2 (Gti 2.16.0, Oct. 2017)
Protocol version 1 is simply the original and current protocol (what I'm calling version 0) with the addition of a single packet line, which precedes the ref advertisement, indicating the protocol version being spoken.
Since v2 improves upon v1, v1 is no longer directly supported: it is either v0 or v2.
And regarding v2, with Git 2.34 (Q4 2021), http-backend has been updated to enable protocol v2 automatically when the other side asks for it, taking advantage of the CGI interface.
See commit 1b421e7, commit 2834a72, commit 295d81b, commit ff6a37c, commit 2614698 (10 Sep 2021) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit cabb41d, 23 Sep 2021)
docs/http-backend
: mention v2 protocolSigned-off-by: Jeff King
Historically there was a little bit of configuration needed at the webserver level in order to get the client's v2 protocol probes to Git.
But when we introduced the v2 protocol, we never documented these.As of the previous commit, this should mostly work out of the box without any explicit configuration.
But it's worth documenting this to make it clear how we expect it to work, especially in the face of webservers which don't provide all headers over the CGI interface.
Or anybody who runs across this documentation but has an older version of Git (or used to have an older version, and wonders why they still have aSetEnvIf
line in their Apache config and whether it's still necessary).
git http-backend
now includes in its man page:
taking advantage of the CGI interface, It also supports Git's more-efficient "v2" protocol if properly configured;
git http-backend
now includes in its man page:
# This is not strictly necessary using Apache and a modern version of # git-http-backend, as the webserver will pass along the header in the # environment as HTTP_GIT_PROTOCOL, and http-backend will copy that into # GIT_PROTOCOL. But you may need this line (or something similar if you # are using a different webserver), or if you want to support older Git # versions that did not do that copying. # # Having the webserver set up GIT_PROTOCOL is perfectly fine even with # modern versions (and will take precedence over HTTP_GIT_PROTOCOL, # which means it can be used to override the client's request). SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0
git http-backend
now includes in its man page:
Clients may probe for optional protocol capabilities (like the v2 protocol) using the
Git-Protocol
HTTP header. In order to support these, the contents of that header must appear in theGIT_PROTOCOL
environment variable. Most webservers will pass this header to the CGI via theHTTP_GIT_PROTOCOL
variable, andgit-http-backend
will automatically copy that toGIT_PROTOCOL
. However, some webservers may be more selective about which headers they'll pass, in which case they need to be configured explicitly (see the mention ofGit-Protocol
in the Apache config from the earlier EXAMPLES section).
git -c protocol.version=1 clone...
used to work in t/interop/i5700-protocol-transition.sh
, but only for Got 2.0.0, not after.
That is because it is an interop test:
This directory has interoperability tests for git.
Each script is similar to the normal test scripts found int/
, but with the added twist that two special versions of git, "git.a
" and "git.b
", are available in thePATH
.
Individual tests can then check the interaction between the two versions.
So protocol.version=1
worked only in Git 2.0.0. Not before or after.
Upvotes: 4
Reputation: 489333
There is no "Git protocol v1". There is version zero, which is the first version (which you could call "v1" if you wanted, but Git does not); and then there is version 2, which is the second version. So the valid choices are v0 and v2.
Upvotes: 1
Reputation: 1959
The differences between version Git Protocol v1 and version 2 is,
This document presents a specification for a version 2 of Git’s wire protocol. Protocol v2 will improve upon v1 in the following ways:
Instead of multiple service names, multiple commands will be supported by a single service
Easily extendable as capabilities are moved into their own section of the protocol, no longer being hidden behind a NUL byte and limited by the size of a pkt-line
Separate out other information hidden behind NUL bytes (e.g. agent string as a capability and symrefs can be requested using ls-refs)
Reference advertisement will be omitted unless explicitly requested
ls-refs command to explicitly request some refs
Designed with http and stateless-rpc in mind. With clear flush semantics the http remote helper can simply act as a proxy
In protocol v2 communication is command oriented. When first contacting a server a list of capabilities will advertised. Some of these capabilities will be commands which a client can request be executed. Once a command has completed, a client can reuse the connection and request that other commands be executed.
More information on Protocol v2 in the Git documentation, https://git-scm.com/docs/protocol-v2
Upvotes: -2