зеркало из https://github.com/microsoft/git.git
protocol: introduce protocol extension mechanisms
Create protocol.{c,h} and provide functions which future servers and clients can use to determine which protocol to use or is being used. Also introduce the 'GIT_PROTOCOL' environment variable which will be used to communicate a colon separated list of keys with optional values to a server. Unknown keys and values must be tolerated. This mechanism is used to communicate which version of the wire protocol a client would like to use with a server. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
5d2124b34a
Коммит
373d70efb2
|
@ -2517,6 +2517,23 @@ The protocol names currently used by git are:
|
||||||
`hg` to allow the `git-remote-hg` helper)
|
`hg` to allow the `git-remote-hg` helper)
|
||||||
--
|
--
|
||||||
|
|
||||||
|
protocol.version::
|
||||||
|
Experimental. If set, clients will attempt to communicate with a
|
||||||
|
server using the specified protocol version. If unset, no
|
||||||
|
attempt will be made by the client to communicate using a
|
||||||
|
particular protocol version, this results in protocol version 0
|
||||||
|
being used.
|
||||||
|
Supported versions:
|
||||||
|
+
|
||||||
|
--
|
||||||
|
|
||||||
|
* `0` - the original wire protocol.
|
||||||
|
|
||||||
|
* `1` - the original wire protocol with the addition of a version string
|
||||||
|
in the initial response from the server.
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
pull.ff::
|
pull.ff::
|
||||||
By default, Git does not create an extra merge commit when merging
|
By default, Git does not create an extra merge commit when merging
|
||||||
a commit that is a descendant of the current commit. Instead, the
|
a commit that is a descendant of the current commit. Instead, the
|
||||||
|
|
|
@ -697,6 +697,12 @@ of clones and fetches.
|
||||||
which feed potentially-untrusted URLS to git commands. See
|
which feed potentially-untrusted URLS to git commands. See
|
||||||
linkgit:git-config[1] for more details.
|
linkgit:git-config[1] for more details.
|
||||||
|
|
||||||
|
`GIT_PROTOCOL`::
|
||||||
|
For internal use only. Used in handshaking the wire protocol.
|
||||||
|
Contains a colon ':' separated list of keys with optional values
|
||||||
|
'key[=value]'. Presence of unknown keys and values must be
|
||||||
|
ignored.
|
||||||
|
|
||||||
Discussion[[Discussion]]
|
Discussion[[Discussion]]
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -842,6 +842,7 @@ LIB_OBJS += pretty.o
|
||||||
LIB_OBJS += prio-queue.o
|
LIB_OBJS += prio-queue.o
|
||||||
LIB_OBJS += progress.o
|
LIB_OBJS += progress.o
|
||||||
LIB_OBJS += prompt.o
|
LIB_OBJS += prompt.o
|
||||||
|
LIB_OBJS += protocol.o
|
||||||
LIB_OBJS += quote.o
|
LIB_OBJS += quote.o
|
||||||
LIB_OBJS += reachable.o
|
LIB_OBJS += reachable.o
|
||||||
LIB_OBJS += read-cache.o
|
LIB_OBJS += read-cache.o
|
||||||
|
|
8
cache.h
8
cache.h
|
@ -445,6 +445,14 @@ static inline enum object_type object_type(unsigned int mode)
|
||||||
#define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS"
|
#define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS"
|
||||||
#define GIT_QUARANTINE_ENVIRONMENT "GIT_QUARANTINE_PATH"
|
#define GIT_QUARANTINE_ENVIRONMENT "GIT_QUARANTINE_PATH"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Environment variable used in handshaking the wire protocol.
|
||||||
|
* Contains a colon ':' separated list of keys with optional values
|
||||||
|
* 'key[=value]'. Presence of unknown keys and values must be
|
||||||
|
* ignored.
|
||||||
|
*/
|
||||||
|
#define GIT_PROTOCOL_ENVIRONMENT "GIT_PROTOCOL"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This environment variable is expected to contain a boolean indicating
|
* This environment variable is expected to contain a boolean indicating
|
||||||
* whether we should or should not treat:
|
* whether we should or should not treat:
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "cache.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
static enum protocol_version parse_protocol_version(const char *value)
|
||||||
|
{
|
||||||
|
if (!strcmp(value, "0"))
|
||||||
|
return protocol_v0;
|
||||||
|
else if (!strcmp(value, "1"))
|
||||||
|
return protocol_v1;
|
||||||
|
else
|
||||||
|
return protocol_unknown_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum protocol_version get_protocol_version_config(void)
|
||||||
|
{
|
||||||
|
const char *value;
|
||||||
|
if (!git_config_get_string_const("protocol.version", &value)) {
|
||||||
|
enum protocol_version version = parse_protocol_version(value);
|
||||||
|
|
||||||
|
if (version == protocol_unknown_version)
|
||||||
|
die("unknown value for config 'protocol.version': %s",
|
||||||
|
value);
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return protocol_v0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum protocol_version determine_protocol_version_server(void)
|
||||||
|
{
|
||||||
|
const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);
|
||||||
|
enum protocol_version version = protocol_v0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine which protocol version the client has requested. Since
|
||||||
|
* multiple 'version' keys can be sent by the client, indicating that
|
||||||
|
* the client is okay to speak any of them, select the greatest version
|
||||||
|
* that the client has requested. This is due to the assumption that
|
||||||
|
* the most recent protocol version will be the most state-of-the-art.
|
||||||
|
*/
|
||||||
|
if (git_protocol) {
|
||||||
|
struct string_list list = STRING_LIST_INIT_DUP;
|
||||||
|
const struct string_list_item *item;
|
||||||
|
string_list_split(&list, git_protocol, ':', -1);
|
||||||
|
|
||||||
|
for_each_string_list_item(item, &list) {
|
||||||
|
const char *value;
|
||||||
|
enum protocol_version v;
|
||||||
|
|
||||||
|
if (skip_prefix(item->string, "version=", &value)) {
|
||||||
|
v = parse_protocol_version(value);
|
||||||
|
if (v > version)
|
||||||
|
version = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string_list_clear(&list, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum protocol_version determine_protocol_version_client(const char *server_response)
|
||||||
|
{
|
||||||
|
enum protocol_version version = protocol_v0;
|
||||||
|
|
||||||
|
if (skip_prefix(server_response, "version ", &server_response)) {
|
||||||
|
version = parse_protocol_version(server_response);
|
||||||
|
|
||||||
|
if (version == protocol_unknown_version)
|
||||||
|
die("server is speaking an unknown protocol");
|
||||||
|
if (version == protocol_v0)
|
||||||
|
die("protocol error: server explicitly said version 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef PROTOCOL_H
|
||||||
|
#define PROTOCOL_H
|
||||||
|
|
||||||
|
enum protocol_version {
|
||||||
|
protocol_unknown_version = -1,
|
||||||
|
protocol_v0 = 0,
|
||||||
|
protocol_v1 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used by a client to determine which protocol version to request be used when
|
||||||
|
* communicating with a server, reflecting the configured value of the
|
||||||
|
* 'protocol.version' config. If unconfigured, a value of 'protocol_v0' is
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
extern enum protocol_version get_protocol_version_config(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used by a server to determine which protocol version should be used based on
|
||||||
|
* a client's request, communicated via the 'GIT_PROTOCOL' environment variable
|
||||||
|
* by setting appropriate values for the key 'version'. If a client doesn't
|
||||||
|
* request a particular protocol version, a default of 'protocol_v0' will be
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
extern enum protocol_version determine_protocol_version_server(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used by a client to determine which protocol version the server is speaking
|
||||||
|
* based on the server's initial response.
|
||||||
|
*/
|
||||||
|
extern enum protocol_version determine_protocol_version_client(const char *server_response);
|
||||||
|
|
||||||
|
#endif /* PROTOCOL_H */
|
Загрузка…
Ссылка в новой задаче