文档章节

码云即将支持 Git v2 Protocol

Force武装卫队
 Force武装卫队
发布于 2018/05/23 15:53
字数 1587
阅读 1628
收藏 1

美国当地时间 5月18日 Google 开发者发布了一篇博客 Introducing Git protocol version 2 宣布了 Git v2 Protocol,v2 协议又叫做 Git Wire Protocol,新协议旨在改进 Git 的传输过程。

通常情况下,Git 传输协议 (v1 smart protocol)是非常高效的,但是当一个存储库体积巨大或者引用(分支)数目巨多时,这个结论不再有效,此时用户体验将变得非常差。

在 v1 协议中,任何请求都是从发现引用开始,比如 git clone https://host/repo.git 的第一步就是 GET /repo.git/info/refs?service=git-upload-pack,这个时候,服务器要列出所有的引用,如果存在一万个引用就意味着一万个引用都需要解析然后传输,而基于 Pull-Request 模型的开发流程这种情况将更加突出(每一次创建一个 PR 相当于创建若干引用),这就给 Git 的传输带来了很大的压力,用户也需要花费更长的时间等待。

在 v1 协议中,git 传输的扩展性非常差,git 智能协议实际上并不智能,智能传输实际上仅仅是两组命令输入输出的交换,输入输出仅仅是计算好的数据,并且没有考虑到扩展性。以 HTTP 浅表克隆为例 , git 需要协商需要的 commit 深度,由于 HTTP 协议是无状态协议,请求流程是 Request-Response ,因此在第一个 HTTP post 请求时,fetch-pack 需要输出 depth 的值,然后等待 upload-pack 计算此上限 commit id,fetch-pack 再次发送请求告知 upload-pack 需要的上限 commitid,在 v1 协议中只能别扭的实现此功能,Http Git 服务器开发者也需要注意此处需要及时的让 git-upload-pack 退出,否则会出现竞争长时间挂起。

而在 v2 协议中,虽然还是两组命令输入输出的交换,但这些输入输出中还可以携带要执行的命令。此时的浅表克隆可以以命令加参数的形式通知服务器,服务器上相应的命令直接计算当前分支最新的 commit 以及 deepen 值即可,简化了传输流程。

这里有一个 v1 与 v2 的简短比较

细节Git Smart ProtocolGit Wire Protocol
协议细节一对命令的输入输出交换一组命令的输入输出交换
git-fetch-pack/git-upload-packls-refs(get refs),fetch(fetch pack)
git-send-pack/git-upload-packpush 暂未利用 Wire Protocol
数据格式pktlinepktline

查看协议内容:protocol-v2 我们可以发现主要是 Capability AdvertisementCommand RequestCapabilities 能够更好的指定 capabilities,特定的 command

为了方便读者直观了解,这里有两个 Gist 片段 https://gitee.com/ipvb/codes/y1b4ew3vqfgom5298iznh69 分别是 v1 和 v2 传输协议的抓包分析。

由于 Git 2.18 还未发布,用户想直接用上 v2 功能得直接从源码构建 Git。在 Git 的 pu 分支,我们还发现协议相对于 master 分支有所修改,主要是增加了 filter 这个功能主要是为了支持部分检出,类似与 Git GVFS,这种功能将极大的优化巨型存储库的访问,这正是 v2 扩展性好的体格体现。

If the 'filter' feature is advertised, the following argument can be
included in the client's request:

    filter <filter-spec>
	Request that various objects from the packfile be omitted
	using one of several filtering techniques. These are intended
	for use with partial clone and partial fetch operations. See
	`rev-list` for possible "filter-spec" values.

v2 与 v1 协议最大的区别在于,v1 协议是基于服务 (service) 的,服务功能单一,fetch-pack ---> upload-packfetchsend-pack ---> receive-packpush,而 v2 协议则变成了可以执行多个命令,这与 svn 协议又有了相似之处。不同类型的版本控制系统也在互相吸取经验。

Wire Protocol 协议的内容可以在这里找到。

码云的进展

笔者在了解到 v2 协议发布后,花了几天实现了对 v2 协议的兼容。

HTTP 协议需要检测请求头中是否有 Git-Protocol 然后 GET 请求时不再输出 # service=git-upload-pack 这样的标志,添加环境变量 GIT_PROTOCOL=version=2 去执行 git-upload-pack/git-receive-pack.

SSH 协议支持 SetEnv 修改环境变量,所以只要接受客户端的 SetEnv 请求,然后和 HTTP 一样即可,SSH 没有 # service=xx 因此也没有那一不需要修改。

Git 协议需要重新解析数据头,判断是否存在 version=2,类似头部 003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0

码云架构早已经变成了分布式的, 我们拥有统一的 Git 传输服务 git-srv 有 HTTP/SSH/GIT 适配,在与 git-srv 协商时,增加一个 version 字段,然后 git-srv 在启动 git 命令时,如果发现不为空就设置环境变量即可。

目前包括 Git SSH HTTP 协议都已经做到了兼容 v2 协议。但由于 Git 2.18 还未释放,协议也在改进,这些x新功能也需要一些时日才能上线。

NameProtocolTechv2 Statusdescription
Basalt SshdSSHC++,libsshOKbackend git-srv
BrzoHTTPC++, asioOKbackend git-srv
BoiteGitC++,asioOKbackend git-srv
Git-diamondGitC++,asioOKInternal Transfer Server
Basalt Sshd (Go)SSHGoOKDistributed, backend git-srv
BsshdSSHGoOKSingle Machine
BrzoxHTTPGoOKbackend git-srv
BrackHTTPGoOKSingle Machine

Go 的单机版主要是为一些小企业优化。

如何使用

用户需要从源码编译 git . 然后找到一个支持 v2 的服务器,目前主流的 Git 托管平台都暂不支持(除了 Google 的),官方的 git-http-backend 支持,这里有一个笔者贡献的 git-http-backend 已经支持:https://github.com/asim/git-http-backend。 需要注意服务器上的 git 也需要是最新版,否则无法使用。

git -c protocol.version=2 clone http://domian/repo.git

为了简化操作,可以在 .zshrc 或者 .bashrc 中新建别名:

alias git2='/path/to/git/installdir/bin/git -c protocol.version=2'

检测远程服务器是否支持 v2

GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote

大家有更多的疑问可以去 https://gitee.com/oscstudio/git/issues 打开一个 Issues。

彩蛋:https://gitee.com/oscstudio/git 的 HTTP2 分支支持 HTTP2,需要服务器支持。

© 著作权归作者所有

共有 人打赏支持
Force武装卫队

Force武装卫队

粉丝 185
博文 39
码字总数 77000
作品 3
深圳
高级程序员
私信 提问
加载中

评论(12)

Force武装卫队
Force武装卫队

引用来自“Fedo”的评论

这与 svn 协议又有了相似指出。😬 指出
谢谢,已修改。
Fedo
Fedo
这与 svn 协议又有了相似指出。😬 指出
cyper
cyper
厉害了我的薯
久永
久永
好厉害,必须顶一下!
好长时间没有研究 git 协议了,现在已经落伍了。
ddatsh
ddatsh

引用来自“Tom-Lin”的评论

厉害了,我的云
厉害了这评论说出了我想说的 哈哈
itfanr
itfanr
6666
Tom-Lin
Tom-Lin
厉害了,我的云
皇虫
皇虫
厉害了我的码
idreamblue
idreamblue
foy
foy
6666666
码云已经支持 Git Wire Protocol

前言 两个半月前,Google 开发者宣布了 Git Wire Protocol,即 Git v2 协议,Git Wire Protocol 协议改进了 Git 的传输过程,增加了可扩展性。关于协议的背景和细节介绍,大家可以去 《码云即...

Force武装卫队
2018/09/05
0
8
项目迁移:从码云迁移到Github

之前因为某些原因,在码云gitee创建了一些项目,无奈到后来发觉码云生态活跃度还是不能和github比的,于是打算把项目迁移到github上。 但是项目迁移却遇到了问题,码云支持从Github导入,Gith...

赵客缦胡缨v吴钩霜雪明
2018/11/22
0
0
Git@OSC 安卓手机客户端测试版发布

为什么我要把代码放到 Git@OSC 平台上? 不限数量的公有库和私有库,承诺永久免费 利用开源中国社区使项目得到充分推广 代码托管是开源中国核心产品,可靠才最重要 VIP 服务,有问题 @红薯 ...

oschina
2014/07/30
10.3K
112
将项目同时托管到Github和Git@OSC

GIT@OSC是国内最大的git代码托管平台,支持免费私有库,支持SVN操作,用户众多。 很多开发者希望在不同的代码托管平台都有托管一份,这个对于git来说并不是一件麻烦的事情,而GIT@OSC也支持从...

Force武装卫队
2015/04/21
0
40
使用Git将项目托管到码云及从码云导入项目到本地

前言 码云+Git+IntellJ IDEA 欢迎转载,请注明作者和出处哦☺ Git 的安装及使用的教程 最好不要在官网下载,官网下载要vpn而且速度还很慢 。 推荐在 https://github.com/waylau/git-for-win ...

我不是陈浩南
2018/12/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

RabbitMQ入门

RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue)协议的开源实现。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都非常的优秀。是当前最主流的消息中间...

watermelon11
今天
15
0
今天的学习

自动加载:方法一 function __autoload( $className ){在这里,完成加载B这个类文件的工作。}class A{} //这是一个类$a1 = new A(); //这里没有自动加载的发生,因为A这个类...

墨冥
今天
2
0
印刷工艺步骤

印刷厂从收到订单到交付整个流程,一般涉及到以下步骤 1.设计(经过软件如cdr,psd,ai等等设计需要印刷的名片,宣传单,画册等物料); 2.排版拼版(在电脑软件这区域完成); 3.出版、出硫...

focusone
昨天
3
0
virtualbox中安装ubuntu

virtualbox+ubuntu 安装virtualbox,当前版本是6.0.4 下载ubuntu安装盘,建议lubuntu,链接是http://mirrors.ustc.edu.cn/ubuntu-cdimage/lubuntu/releases/18.04.2/release/lubuntu-18.04.......

chuqq
昨天
5
0
exists 谓词的子查询

https://blog.csdn.net/qq_19782019/article/details/78730882

仟昭
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部