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 protocols 和 Documentation Common to Pack and Http Protocols
在协议 v2 中,这些特殊数据包将具有以下语义:
0000 Flush Packet
( flush-pkt ) - 表示消息的结束0001 Delimiter Packet
(delim-pkt) - 用于分隔消息的各个部分
初始化客户端请求
一般来说,客户端可以在正在使用的传输上通过相应的侧信道请求发送 version=2
说明使用协议 v2。这一般是通过设置 GIT_PROTOCOL
环境变量达成的。
更多详细的信息,可以访问 Packfile transfer protocols 和 HTTP 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 | " -_.,?\/{}[]()<>!@#$%^&*+=:;")
暂停
有点急事,以后再回来填坑