Git 协议 v1 和 v0,v2 有什么区别?

问题描述

如果我使用协议 v0 和 v2 克隆一个 repo,则一切正常。 但是如果我将协议更改为 v1,我会得到这个:

$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'

错误信息来自 check_smart_http() 方法,我知道协议 v2 和 v0 都是智能协议,但 v1 智能协议不一样吗?

在这里贴出 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);
    }
}

我不明白为什么它忽略了版本 1。

解决方法

没有“Git 协议 v1”。有版本零,这是第一个版本(如果需要,您可以调用“v1”,但 Git 不会);然后是版本 2,这是第二个版本。所以有效的选择是 v0 和 v2。

,

版本 Git 协议 v1 和版本 2 之间的区别是,

本文档介绍了 Git 有线协议第 2 版的规范。协议 v2 将在以下方面改进 v1:

一个服务将支持多个命令,而不是多个服务名称

易于扩展,因为功能被移动到协议的它们自己的部分,不再隐藏在 NUL 字节后面并受到 pkt 行大小的限制

分离出隐藏在 NUL 字节后面的其他信息(例如,代理字符串作为一种能力,可以使用 ls-refs 请求 symrefs)

除非明确要求,否则将省略参考广告

ls-refs 命令显式请求一些引用

在设计时考虑了 http 和 stateless-rpc。通过清晰的刷新语义,http 远程助手可以简单地充当代理

在协议 v2 中,通信是面向命令的。当第一次联系服务器时,将公布功能列表。其中一些功能将是客户端可以请求执行的命令。命令完成后,客户端可以重用连接并请求执行其他命令。

Git 文档中有关协议 v2 的更多信息, https://git-scm.com/docs/protocol-v2