Git TCP 传输协议第二版

yufei       4 年 前       590

Git 在不久前释出了它们的新的传输协议,名字为 Git Wire Protocol, Version 2

官网网址为 https://mirrors.edge.kernel.org/pub/software/scm/git/docs/technical/protocol-v2.html

出于好奇,也出于了解 Git 的传输过程,特翻译于此

P.S 一贯的风格,不是 100% 原滋原味翻译,而是会添加一些个人见解。


Git 传输协议,第二版

本文档介绍了 Git 传输协议版本 2 的规范。协议 v2 将通过以下方式改进 v1:

  • 单次服务支持多个命令,而不是 v1 中的多个命令需要多次服务。

  • 为了便于扩展,将功能分解到协议中的各个部分,而不像 v1 中隐藏在 NUL 类型后面且受到 pkt-line 大小的限制。 ( P.S 这句翻译可能是错的,尤其是对 Easily extendable as capabilities 的翻译 )

  • 分离隐藏在 NUL 字节后面的其它信息 ( 例如代理字符串功能,并且可以使用 ls-refs 请求 symrefs

  • 除非明确要求,否则将省略引用公告

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

  • 设计时考虑到 HTTP 和无状态 RPC。使用明确的 clear flush 语义,HTTP 远程帮助程序可以简单地充当代理

在协议 v2 版本中,通信是面向命令的。首次联络服务器时,就会获得一个可用功能的公告列表,其中一些功能将是客户端可以请求执行的命令。当一个命令完成后,客户端可以重用连接并请求执行其它命令。

Packet-Line Framing

P.S Packet-Line Framing 真不知道怎么翻译,就直接放原文了

v2 版本中所有的通讯都使用 Packet-Line Framing 完成,就像 v1 中的那样。更多详细信息,可以查看 Packfile transfer protocolsDocumentation Common to Pack and Http Protocols

在协议 v2 中,这些特殊数据包将具有以下语义:

  • 0000 Flush Packet( flush-pkt ) - 表示消息的结束
  • 0001 Delimiter Packet (delim-pkt) - 用于分隔消息的各个部分

初始化客户端请求

一般来说,客户端可以在正在使用的传输上通过相应的侧信道请求发送 version=2 说明使用协议 v2。这一般是通过设置 GIT_PROTOCOL 环境变量达成的。

更多详细的信息,可以访问 Packfile transfer protocolsHTTP transfer protocols

所有情况下,服务器的响应都是功能公告。

Git 传输

当使用 git:// 协议传输时,我们可以使用一个额外参数发送 version = 2 来请求使用 v2 协议,就像下面这样

003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0

SSH 和文件传输

当使用 ssh://file:// 协议传输时,必须明确设置 GIT_PROTOCOL 环境变量包含 version = 2

HTTP 传输

当使用 http://https:// 协议传输时,客户端可以像 HTTP transfer protocols 中所描述的那样,发起一个 「 智能 」的 info/refs 请求,并添加 Git-Protocol:version=2 请求头部信息,就像下面这样

GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
Git-Protocol: version=2

然后 v2 服务器必须翻译一个类似下面这样的响应

200 OK
<Some headers>
...

000eversion 2\n
<capability-advertisement>

然后,后续请求直接发送到服务地址 $GIT_URL/git-upload-pack 。( 这对 git-receive-pack 也是一样的)

功能公告

决定使用协议版本 2 进行通信 ( 基于来自客户端的请求 ) 的服务器,通过在其初始响应中发送版本字符串,然后发布其功能来通知客户端该服务器支持的功能。

每个功能都是一个键,紧跟着一个可选的值。

客户端必须忽略所有自己不能识别的键 ( 也就是未知键 )。

至于哪些是 「 未只键 」及其相关语义留给键自己定义。

而一些功能则表示客户端可以发起的命令请求。

capability-advertisement = protocol-version
                           capability-list
                           flush-pkt
protocol-version = PKT-LINE("version 2" LF)
capability-list = *capability
capability = PKT-LINE(key[=value] LF)
key = 1*(ALPHA | DIGIT | "-_")
value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;")

暂停

有点急事,以后再回来填坑

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.